For the latest stable version, please use Spring Framework 6.2.1! |
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")
}
}