WebMvcTest

ResultMatcher for .addExpect

Let’s say we save some list of items and then read it back. Here is our original list:

List<MyItem> myItemList = new ArrayList<MyItem>() {{
        add( new MyItem() {{
            title = "Test Item 1";
        }});
        add( ... );
        ...
    }};

And we have mockMvc defined like:

@Autowired MockMvc mvc;

We can store the list with mvc.perform( put("/api/myitem/list" )).andExpect( status().isOk() ).

We can read the list with mvc.perform( get("/api/myitem/list" )).andExpect( status().isOk() ). But!

The problem

We do not have database ids in our original list. So .andExpect( content().json( myItemListAsJsonString ) ) will give us false-negative result.

Solution - use lambda callback for comparison

this.mvc.perform(get("/api/myitem/list"))
    .andExpect( status().isOk() )
    .andExpect( (result)->{ // lambda for ResultMatcher
                            // return void
                            // if result not match expectation - we should throw exception
    
        String jsonString = result.getResponse().getContentAsString();
        List<MyItem> storedMyItemList = objectMapper.readValue(jsonString, 
                                            new TypeReference<List<MyItem>>(){});
        for( MyItem storedItem : storedMyItemList) {
            myItemList.stream().filter( x -> storedItem.title.equals(x.title))
                .findFirst().orElseThrow(
                    () -> { // lambda for exception
                        throw new AssertionError("MyItem not found, expected: \n"
                            + myItemListAsJsonString + "\nactual: \n" + jsonString
                            + "myitem.id field is ignored"
                        );
                    }
                );
        }
    });