Как да проверите returntype в Spring Unittest с помощта на MockMVC?

Пролетният метод, който искам да тествам

@RequestMapping(value="/files", method=RequestMethod.GET)
@ResponseBody
public List<FileListRequest> get() {
   return getMainController().getAllFiles();
}

Искам да съм сигурен, че на всички обаждания към /files се отговаря със списък [FileListRequest]. Как?
Това е методът, по който трябва да бъде тестът.

@Test
public void testGetAll() throws Exception {
    this.mockMvc.perform(get("/files").accept("application/json"))
            .andExpect(status().isOk())
            .andExpect(content().contentType(SOMETHING);
}

Мога ли просто да заменя НЕЩО или греша тотално?

Мога ли да стартирам assert методи на обекта, върнат от perform()?


person Ricardo    schedule 05.03.2016    source източник
comment
можете да използвате json path, за да проверите дали отговорът съдържа конкретните данни   -  person Pragnani    schedule 05.03.2016


Отговори (2)


Редактиране:

MvcResult result =   this.mockMvc.perform(get("/files").accept("application/json"))
            .andExpect(status().isOk())
             .andReturn();

String content = result.getResponse().getContentAsString();

// Конвертиране на json низ в съответен обект с помощта на Gson или Jackson

ObjectMapper mapper = new ObjectMapper();
TypeFactory typeFactory=objectMapper.getTypeFactory();
List<SomeClass> someClassList =mapper.readValue(content , typeFactory.constructCollectionType(List.class, SomeClass.class));

//Потвърдете тук с вашия списък


Можете да използвате Json Path, за да проверите дали във вашия отговор съществуват конкретни данни

снипер на код от стар проект

mockMvc.perform(get("/rest/blogs")) .contentType(MediaType.APPLICATION_JSON))
                .andExpect(jsonPath("$.blogs[*].title",
                        hasItems(endsWith("Title A"), endsWith("Title B"))))
                .andExpect(status().isOk());
person Pragnani    schedule 05.03.2016
comment
Има ли начин да работя директно с очаквания върнат обект, в този случай списъка? - person Ricardo; 05.03.2016
comment
@John Да.. Ще актуализирам отговора с редактиране, но не се препоръчва да тествате отговора на почивка като този. - person Pragnani; 05.03.2016
comment
Добре. Има само 1 нещо, което трябва да проверя: дали типът на връщане е очакваният тип на връщане (има ли върнат списък, ...). Какво е точното съдържание на върнатия обект, в момента няма значение. - person Ricardo; 05.03.2016
comment
@John провери редакцията ми. Не съм пробвал, но се надявам да се получи - person Pragnani; 05.03.2016
comment
Добре! Каква е причината простата проверка на типа да е толкова сложна за извършване с MockMVC? - person Ricardo; 05.03.2016
comment
@John Не съм сигурен, защото никога не съм опитвал да проверя типа на връщане за отговора. Може да има начин, моля, изчакайте още отговори - person Pragnani; 05.03.2016

  1. Не можете да използвате contentType за проверка на класа на екземплярите. Content-Type трябва да определи формата на текста, изпратен/върнат в HTTP(S) заявка/отговор и няма нищо общо с програмната проверка на типа. Той само регламентира, че заявката/отговорът е в json/text-plain/xml и т.н.

  2. За да проверим типа на обектите, върнати в отговора, нека приемем, че отговорът е във формат JSON (вграденият Jackson в Spring boot ще извърши (не)маршалирането) и просто използваме org.hamcrest.Matchers.instanceOf(Class<?> type), за да проверим класа на първия елемент в списъка, с jsonPath.

Работен фрагмент:

import static org.hamcrest.Matchers.instanceOf;

...

@Test
public void testBinInfoControllerInsertBIN() throws Exception {
    when(this.repository.save(mockBinInfo)).thenReturn(mockBinInfo);

    this.mockMvc.perform(post("/insert")
            .content("{\"id\":\"42\", \"bin\":\"touhou\", \"json_full\":\"{is_json:true}\", \"createAt\":\"18/08/2018\"}")
            .accept(MediaType.APPLICATION_JSON_UTF8_VALUE)
            .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)
            )
        .andExpect(content().contentType(MediaType.APPLICATION_JSON_UTF8_VALUE))
        .andExpect(status().isCreated())
        .andExpect(jsonPath("$[0]", instanceOf(BinInfo.class)))
        .andExpect(jsonPath("$[0].bin", is("touhou")));


}

Ако искате да проверите всеки елемент в списъка... може би е излишен? Не съм виждал код, който да проверява всеки елемент в списъка, защото трябва да повтаряте. Има начин, разбира се.

person WesternGun    schedule 16.07.2018