简体   繁体   中英

How to match List of Objects in MockMvc Spring Test?

I have a MockMVC test that returns a list of objects. I am trying to check this specific property is set correctly.

However I cannot get it to match using any way, apart from by explicitly adding it. KeyPair is a simple pair class with a key value, very similar to an entry of a map.

     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 ) ) );

I have tried a few options

is( keyList )

is( keyList.toString() )

is( Gson.toJson(keylist )

is( mapper.writeValueAsString(keyList) (jackson serialisation)

However keep getting different mismatch messages:

    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 "}]>

I don't want to write json in the test as seems a bit rubbish / fragile. So does anybody know how to map it?

The problem is that JsonPath parse $.contactDetails as a String and you compare it with List<>. You can transform keyList to string and compare then.

In case of parsing $.contactDetails to list i can advice a Gson library

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);

Try this out

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

The issue seems to be as follows jsonPath( "$.contactDetails") return a JsonObject kind of Structure while gson.toJson(keyList ) returns a String which contains the Json with escaping done for quotes.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM