Как сопоставить список объектов в весеннем тесте MockMvc?

У меня есть тест MockMVC, который возвращает список объектов. Я пытаюсь проверить правильность установки этого конкретного свойства.

Однако я не могу заставить его соответствовать каким-либо образом, кроме явного добавления. KeyPair — это простой парный класс со значением ключа, очень похожий на запись карты.

     List<KeyPair<String, String>> keyList = User.getContactDetails()
        .entrySet()
        .stream()
        .map( e -> new KeyPair<String, String>( e ) )
        .collect( Collectors.toList() );

      performQueryWithHeaders( get( "/users/1" ) )
            .andExpect( status().isOk() )
            .andExpect( jsonPath( "$.contactDetails" ,
                  is( keyList ) ) );

Я пробовал несколько вариантов

есть (список ключей)

(keyList.toString())

есть (Gson.toJson (список ключей)

is(mapper.writeValueAsString(keyList) (сериализация Джексона)

Однако продолжайте получать разные сообщения о несоответствии:

    JSON path "$.contactDetails"
Expected: is "[{\"key\":\"example title\",\"value\":\"example title\"},    {\"key\":\"another example\",\"value\":\"another example\"},{\"key\":\"etc \",\"value\":\"etc \"}]"
     but: was <[{"key":"example title","value":"example title"},{"key":"another example","value":"another example"},{"key":"etc ","value":"etc "}]>

 JSON path "$.contactDetails"
Expected: is <[KeyPair(key=example title, value=example title), KeyPair(key=another example, value=another example), KeyPair(key=etc , value=etc )]>
 but: was <[{"key":"example title","value":"example title"},{"key":"another example","value":"another example"},{"key":"etc ","value":"etc "}]>

 JSON path "$.contactDetails"
Expected: is "[KeyPair(key=example title, value=example title), KeyPair(key=another example, value=another example), KeyPair(key=etc , value=etc )]"
 but: was <[{"key":"example title","value":"example title"},{"key":"another example","value":"another example"},{"key":"etc ","value":"etc "}]>

 JSON path "$.contactDetails"
Expected: is "[{\"key\":\"example title\",\"value\":\"example title\"},{\"key\":\"another example\",\"value\":\"another example\"},{\"key\":\"etc \",\"value\":\"etc \"}]"
 but: was <[{"key":"example title","value":"example title"},{"key":"another example","value":"another example"},{"key":"etc ","value":"etc "}]>

Я не хочу писать json в тесте, так как это кажется немного мусорным/хрупким. Так кто-нибудь знает, как это сделать?


person Nyxter    schedule 02.02.2017    source источник


Ответы (2)


Проблема в том, что JsonPath анализирует $.contactDetails как строку, и вы сравниваете ее со списком‹>. Вы можете преобразовать keyList в строку и затем сравнить.

В случае парсинга $.contactDetails в список я могу посоветовать библиотеку Gson

import java.lang.reflect.Type;
import com.google.gson.reflect.TypeToken;
// ...
Type listType = new TypeToken<List<KeyPair<String, String>>>() {}.getType();
List<KeyPair<String, String>> yourList = new Gson().fromJson(JsonPath.parse("$.contactDetails")), listType);
person Sergii Getman    schedule 02.02.2017
comment
Я не совсем уверен, как изменить его на требуемую строку. Я пробовал .toString, а затем сериализовал его в json, используя как gson.toJson, так и сопоставители объектов jackson, но все равно не правильно сопоставил. - person Nyxter; 02.02.2017

Попробуйте это

performQueryWithHeaders( get( "/users/1" ) )
            .andExpect( status().isOk() )
            .andExpect( gson.toJson(jsonPath( "$.contactDetails") ,
                  is( gson.toJson(keyList ) ) );

Проблема выглядит следующим образом: jsonPath( "$.contactDetails") возвращает тип структуры JsonObject, а gson.toJson(keyList ) возвращает строку, содержащую Json с экранированием, выполненным для кавычек.

person Kaushik Patel    schedule 05.02.2017