Defining Expectations
在执行请求后,你可以通过追加一个或多个 andExpect(..)
调用来定义期望,如下面的示例所示。只要有一个期望失败,就不会断言其他期望。
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() }
}
在执行请求后,你可以通过追加 andExpectAll(..)
来定义多个期望,如下面的示例所示。与 andExpect(..)
相反,andExpectAll(..)
保证已提供的所有期望都已断言,并跟踪和报告所有失败。
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.*
提供了许多期望,其中一些期望进一步嵌套了更详细的期望。
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.
第二类的断言超出了响应。通过这些断言,你可以检查 Spring MVC 特定的方面,例如处理请求的 controller 方法、是否引发并处理了异常、模型内容、选择的视图、添加的 flash 属性等。它们还允许你检查 Servlet 特定的方面,例如请求和会话属性。
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")
}
}
在编写测试时,多次转储执行请求的结果非常有用。你可以按照以下步骤操作,其中 print()
是 MockMvcResultHandlers
的静态导入:
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")
}
}
只要请求处理不会导致未处理的异常,print()
方法就会将所有可用的结果数据打印到 System.out
。还有一个 log()
方法和 print()
方法的另外两个变体,一个接受 OutputStream
,另一个接受 Writer
。例如,调用 print(System.err)
会将结果数据打印到 System.err
,而调用 print(myWriter)
会将结果数据打印到自定义 writer。如果你希望记录结果数据而不是打印结果数据,则可以调用 log()
方法,该方法将结果数据作为 org.springframework.test.web.servlet.result
日志类别的单个 DEBUG
消息记录下来。
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.
在某些情况下,你可能希望直接访问结果并验证无法通过其他方式验证的内容。这可以通过在所有其他期望值后面追加 .andReturn()
来实现,如下面的示例所示:
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()
// ...
如果所有测试重复相同的期望,则可以在构建 MockMvc
实例时设置一次共同期望,如下面的示例所示:
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 {kotlin-issues}/KT-22208 is fixed
请注意,共同期望始终被应用,并且无法覆盖,除非创建单独的 MockMvc
实例。
Note that common expectations are always applied and cannot be overridden without
creating a separate MockMvc
instance.
当 JSON 响应内容包含使用https://github.com/spring-projects/spring-hateoas[Spring HATEOAS] 创建的超媒体链接时,您可以使用 JsonPath 表达式来验证所产生的链接,如下例所示:
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")
}
}
当 XML 响应内容包含使用https://github.com/spring-projects/spring-hateoas[Spring HATEOAS] 创建的超媒体链接时,您可以使用 XPath 表达式来验证所得链接:
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")
}
}