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.

  • Java

  • Kotlin

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

mockMvc.perform(get("/accounts/1")).andExpect(status().isOk());
import org.springframework.test.web.servlet.get

mockMvc.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.

  • Java

  • Kotlin

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

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

mockMvc.get("/accounts/1").andExpectAll {
	status { isOk() }
	content { contentType(APPLICATION_JSON) }
}

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 Spring 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:

  • Java

  • Kotlin

mockMvc.perform(post("/persons"))
	.andExpect(status().isOk())
	.andExpect(model().attributeHasErrors("person"));
import org.springframework.test.web.servlet.post

mockMvc.post("/persons").andExpect {
	status { isOk() }
	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:

  • Java

  • Kotlin

mockMvc.perform(post("/persons"))
	.andDo(print())
	.andExpect(status().isOk())
	.andExpect(model().attributeHasErrors("person"));
import org.springframework.test.web.servlet.post

mockMvc.post("/persons").andDo {
		print()
	}.andExpect {
		status { isOk() }
		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 org.springframework.test.web.servlet.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:

  • Java

  • Kotlin

MvcResult mvcResult = mockMvc.perform(post("/persons")).andExpect(status().isOk()).andReturn();
// ...
var mvcResult = mockMvc.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:

  • Java

  • Kotlin

standaloneSetup(new SimpleController())
	.alwaysExpect(status().isOk())
	.alwaysExpect(content().contentType("application/json;charset=UTF-8"))
	.build()
// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed

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

When a JSON response content contains hypermedia links created with Spring HATEOAS, you can verify the resulting links by using JsonPath expressions, as the following example shows:

  • Java

  • Kotlin

mockMvc.perform(get("/people").accept(MediaType.APPLICATION_JSON))
	.andExpect(jsonPath("$.links[?(@.rel == 'self')].href").value("http://localhost:8080/people"));
mockMvc.get("/people") {
	accept(MediaType.APPLICATION_JSON)
}.andExpect {
	jsonPath("$.links[?(@.rel == 'self')].href") {
		value("http://localhost:8080/people")
	}
}

When XML response content contains hypermedia links created with Spring HATEOAS, you can verify the resulting links by using XPath expressions:

  • Java

  • Kotlin

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"));
val ns = mapOf("ns" to "http://www.w3.org/2005/Atom")
mockMvc.get("/handle") {
	accept(MediaType.APPLICATION_XML)
}.andExpect {
	xpath("/person/ns:link[@rel='self']/@href", ns) {
		string("http://localhost:8080/people")
	}
}