How to Check Json in Response Body With Mockmvc

How to check JSON in response body with mockMvc

I use TestNG for my unit testing. But in Spring Test Framework they both looks similar. So I believe your test be like below

@Test
public void testAlertFilterView() throws Exception {
this.mockMvc.perform(get("/getServerAlertFilters/v2v2v2/").
.andExpect(status().isOk())
.andExpect(content().json("{'data':[{'useRegEx':'false','hosts':'v2v2v2'}]}"));
}

If you want check check json Key and value you can use jsonpath
.andExpect(jsonPath("$.yourKeyValue", is("WhatYouExpect")));

You might find thatcontent().json() are not solveble please add

import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

How to check String in response body with mockMvc

@Sotirios Delimanolis answer do the job however I was looking for comparing strings within this mockMvc assertion

So here it is

.andExpect(content().string("\"Username already taken - please try with different username\""));

Of course my assertion fail:

java.lang.AssertionError: Response content expected:
<"Username already taken - please try with different username"> but was:<"Something gone wrong">

because:

  MockHttpServletResponse:
Body = "Something gone wrong"

So this is proof that it works!

How to extract value from JSON response when using Spring MockMVC

I have managed to solve my problem using Spring MockMVC result handler. I created a testing utility to convert the JSON string back to an object and so allowing me to get the ID.

Conversion Utility:

 public static <T>  Object convertJSONStringToObject(String json, Class<T> objectClass) throws IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

JavaTimeModule module = new JavaTimeModule();
mapper.registerModule(module);
return mapper.readValue(json, objectClass);
}

Unit Test:

 @Test
@Transactional
public void createNewWorkWorkWhenCreatedJobItemAndQuantitiesPoolShouldBeCreated() throws Exception {

mockMvc.perform(post("/api/tracker/jobs/work")
.contentType(TestUtil.APPLICATION_JSON_UTF8)
.content(TestUtil.convertObjectToJsonBytes(workRequest)))
.andExpect(status().isCreated())
.andDo(mvcResult -> {
String json = mvcResult.getResponse().getContentAsString();
workRequestResponse = (WorkRequestResponse) TestUtil.convertJSONStringToObject(json, WorkRequestResponse.class);
});

Work work = workService.findWorkById(workRequestResponse.getWorkId());

assertThat(work.getJobItem().getJobItemName()).isEqualTo(workRequest.getJobItem().getJobItemName());
assertThat(work.getJobItem().getQuantities()).hasSize(workRequest.getQuantities().size());
assertThat(work.getJobItem().getQuantityPools()).hasSize(workRequest.getQuantities().size());
}

Is there a method built in spring MockMVC to get json content as Object?

As far as I know MockHttpServletResponse (Unlike RestTemplate) doesn't have any method which could convert returned JSON to a particular type.

So what you could do is use Jackson ObjectMapper to convert JSON string to a particular type

Something like this

String json = rt.getResponse().getContentAsString();
SomeClass someClass = new ObjectMapper().readValue(json, SomeClass.class);

This will give you more control for you to assert different things.

Having said that, MockMvc::perform returns ResultActions which has a method andExpect which takes ResultMatcher. This has a lot of options to test the resulting json without converting it to an object.

For example

mvc.perform(  .....
......
.andExpect(status().isOk())
.andExpect(jsonPath("$.firstname").value("john"))
.andExpect(jsonPath("$.lastname").value("doe"))
.andReturn();

How to check values in response body with mockMvc - AssertionError: Status expected:<201> but was:<400>

You should use @Autowired on your ObjectMapper to make sure it is configured in the same way by Spring as it would be during the application runtime. This would explain the 400 - Bad request error you are getting.

The fact that it is a 409 - Conflict after autowiring the ObjectMapper suggests that this was indeed the error.
Since you do not configure your studentServiceMock in the test, the 409 seems to be the apporiate answer from the controller, because the orElseGet part is being executed.

If I am not mistaken, you could slim down the test class annotations a little and only use @WebMvcTest. This should suffice for this kind of test and it should be a little faster.

MockMVC JsonPath response has empty body?

The problem lies here:

when(service.addNewEmployee(employee)).thenReturn(employee);

Internally Mockito uses an Object class's equals() method to compare object that has been passed to the method as an argument with object configured. If equals() is not overridden then java.lang.Object’s equals() is used which compares only the references, i.e. if both variables point to one and the same object in heap. In the current example, Employe class (probably) has no equals() method implemented. When providing expected a new object is created, references are not one and the same, so Mockito will fail the verification.

Because the employee object is serialized from json, it is not the same object.

You can fix this by using Mockito.any() or Mockito.any(Employee.class).

Spring MockMvc: match a collection of JSON objects in any order

You can assert list items fields ignoring order:

.andExpect(jsonPath("$[*].id", containsInAnyOrder("321", "123")))
.andExpect(jsonPath("$[*].created", containsInAnyOrder("2019-03-01", "2019-03-02")))
.andExpect(jsonPath("$[*].updated", containsInAnyOrder("2019-03-15", "2019-03-16")))

Another approach would be to check that specific list items exist in response:

.andExpect(jsonPath("$.[?(@.id == 123 && @.created == \"2019-03-02\" && @.updated == \"2019-03-16\")]").exists())
.andExpect(jsonPath("$.[?(@.id == 321 && @.created == \"2019-03-01\" && @.updated == \"2019-03-15\")]").exists())



Related Topics



Leave a reply



Submit