Defining Expectations

You can define expectations by appending one or more andExpect(..) calls after performing a request, as the following example shows. As soon as one expectation fails, no other expectations will be asserted.

// static import of MockMvcRequestBuilders.* and MockMvcResultMatchers.*
mockMvc.perform(get("/accounts/1")).andExpect(status().isOk());

You can define multiple expectations by appending andExpectAll(..) after performing a request, as the following example shows. In contrast to andExpect(..), andExpectAll(..) guarantees that all supplied expectations will be asserted and that all failures will be tracked and reported.

// static import of MockMvcRequestBuilders.* and MockMvcResultMatchers.*

mockMvc.perform(get("/accounts/1")).andExpectAll(
	status().isOk(),
	content().contentType("application/json;charset=UTF-8"));

MockMvcResultMatchers.* provides a number of expectations, some of which are further nested with more detailed expectations.

Expectations fall in two general categories. The first category of assertions verifies properties of the response (for example, the response status, headers, and content). These are the most important results to assert.

The second category of assertions goes beyond the response. These assertions let you inspect Web MVC specific aspects, such as which controller method processed the request, whether an exception was raised and handled, what the content of the model is, what view was selected, what flash attributes were added, and so on. They also let you inspect Servlet specific aspects, such as request and session attributes.

The following test asserts that binding or validation failed:

mockMvc.perform(post("/persons"))
  .andExpect(status().isOk())
  .andExpect(model().attributeHasErrors("person"));

Many times, when writing tests, it is useful to dump the results of the performed request. You can do so as follows, where print() is a static import from MockMvcResultHandlers:

mockMvc.perform(post("/persons"))
  .andDo(print())
  .andExpect(status().isOk())
  .andExpect(model().attributeHasErrors("person"));

As long as request processing does not cause an unhandled exception, the print() method prints all the available result data to System.out. There is also a log() method and two additional variants of the print() method, one that accepts an OutputStream and one that accepts a Writer. For example, invoking print(System.err) prints the result data to System.err, while invoking print(myWriter) prints the result data to a custom writer. If you want to have the result data logged instead of printed, you can invoke the log() method, which logs the result data as a single DEBUG message under the cn.taketoday.test.web.mockApi.result logging category.

In some cases, you may want to get direct access to the result and verify something that cannot be verified otherwise. This can be achieved by appending .andReturn() after all other expectations, as the following example shows:

MvcResult mvcResult = mockMvc.perform(post("/persons")).andExpect(status().isOk()).andReturn();
// ...

If all tests repeat the same expectations, you can set up common expectations once when building the MockMvc instance, as the following example shows:

standaloneSetup(new SimpleController())
  .alwaysExpect(status().isOk())
  .alwaysExpect(content().contentType("application/json;charset=UTF-8"))
  .build()

Note that common expectations are always applied and cannot be overridden without creating a separate MockMvc instance.

mockMvc.perform(get("/people").accept(MediaType.APPLICATION_JSON))
  .andExpect(jsonPath("$.links[?(@.rel == 'self')].href").value("http://localhost:8080/people"));
Map<String, String> ns = Collections.singletonMap("ns", "http://www.w3.org/2005/Atom");
mockMvc.perform(get("/handle").accept(MediaType.APPLICATION_XML))
  .andExpect(xpath("/person/ns:link[@rel='self']/@href", ns).string("http://localhost:8080/people"));