Integration Testing POSTing an entire object to Spring MVC controller Integration Testing POSTing an entire object to Spring MVC controller spring spring

Integration Testing POSTing an entire object to Spring MVC controller


I had the same question and it turned out the solution was fairly simple, by using JSON marshaller.
Having your controller just change the signature by changing @ModelAttribute("newObject") to @RequestBody. Like this:

@Controller@RequestMapping(value = "/somewhere/new")public class SomewhereController {    @RequestMapping(method = RequestMethod.POST)    public String post(@RequestBody NewObject newObject) {        // ...    }}

Then in your tests you can simply say:

NewObject newObjectInstance = new NewObject();// setting fields for the NewObject  mockMvc.perform(MockMvcRequestBuilders.post(uri)  .content(asJsonString(newObjectInstance))  .contentType(MediaType.APPLICATION_JSON)  .accept(MediaType.APPLICATION_JSON));

Where the asJsonString method is just:

public static String asJsonString(final Object obj) {    try {        final ObjectMapper mapper = new ObjectMapper();        final String jsonContent = mapper.writeValueAsString(obj);        return jsonContent;    } catch (Exception e) {        throw new RuntimeException(e);    }}  


One of the main purposes of integration testing with MockMvc is to verify that model objects are correclty populated with form data.

In order to do it you have to pass form data as they're passed from actual form (using .param()). If you use some automatic conversion from NewObject to from data, your test won't cover particular class of possible problems (modifications of NewObject incompatible with actual form).


I believe that I have the simplest answer yet using Spring Boot 1.4, included imports for the test class.:

public class SomeClass {  /// this goes in it's own file//// fields go here}import org.junit.Beforeimport org.junit.Testimport org.junit.runner.RunWithimport org.springframework.beans.factory.annotation.Autowiredimport org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTestimport org.springframework.http.MediaTypeimport org.springframework.test.context.junit4.SpringRunnerimport org.springframework.test.web.servlet.MockMvcimport static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.postimport static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status@RunWith(SpringRunner.class)@WebMvcTest(SomeController.class)public class ControllerTest {  @Autowired private MockMvc mvc;  @Autowired private ObjectMapper mapper;  private SomeClass someClass;  //this could be Autowired                                //, initialized in the test method                                //, or created in setup block  @Before  public void setup() {    someClass = new SomeClass();   }  @Test  public void postTest() {    String json = mapper.writeValueAsString(someClass);    mvc.perform(post("/someControllerUrl")       .contentType(MediaType.APPLICATION_JSON)       .content(json)       .accept(MediaType.APPLICATION_JSON))       .andExpect(status().isOk());  }}