|
对于最新稳定版本,请使用 Spring Framework 7.0.6! |
定义期望
您可以在执行请求后附加一个或多个 andExpect(..) 调用以定义预期结果,如下例所示。一旦某个预期失败,将不再断言其他预期。
-
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(..) 能确保所有提供的期望都会被断言,并且所有失败都会被记录并报告。
-
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.* 提供了多种断言,其中一些还嵌套了更详细的断言。
期望值通常分为两大类。第一类断言用于验证响应的属性(例如,响应状态、响应头和响应内容)。这些是最关键的断言结果。
第二类断言超出了响应本身的范畴。这些断言允许您检查 Spring MVC 特有的各个方面,例如哪个控制器方法处理了请求、是否抛出并处理了异常、模型的内容是什么、选择了哪个视图、添加了哪些 Flash 属性等等。它们还允许您检查 Servlet 特有的方面,例如请求和会话属性。
以下测试断言绑定或验证失败:
-
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 静态导入的方法:
-
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) 则会将结果数据打印到自定义的写入器。如果您希望记录结果数据而非直接打印,可以调用 log() 方法,该方法会将结果数据作为单条 DEBUG 消息记录在 org.springframework.test.web.servlet.result 日志类别下。
在某些情况下,你可能希望直接获取结果并验证一些无法通过其他方式验证的内容。这可以通过在所有其他期望之后附加 .andReturn() 来实现,如下例所示:
-
Java
-
Kotlin
MvcResult mvcResult = mockMvc.perform(post("/persons")).andExpect(status().isOk()).andReturn();
// ...
var mvcResult = mockMvc.post("/persons").andExpect { status { isOk() } }.andReturn()
// ...
如果所有测试都重复相同的预期行为,你可以在构建 MockMvc 实例时一次性设置这些公共的预期,如下例所示:
-
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
请注意,通用的期望(expectations)始终会被应用,除非创建一个单独的 MockMvc 实例,否则无法覆盖这些期望。
当 JSON 响应内容包含使用 Spring HATEOAS 创建的超媒体链接时,您可以使用 JsonPath 表达式来验证生成的链接,如下例所示:
-
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 响应内容包含使用 Spring HATEOAS 创建的超媒体链接时,您可以使用 XPath 表达式来验证生成的链接:
-
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")
}
}