执行请求
本节展示如何单独使用MockMvc执行请求并验证响应。如果使用MockMvc通过WebTestClient
,请参阅相应的编写测试部分。
要执行使用任何HTTP方法的请求,如下例所示:
-
Java
-
Kotlin
// MockMvcRequestBuilders的静态导入.*
mockMvc.perform(post("/hotels/{id}", 42).accept(MediaType.APPLICATION_JSON));
import org.springframework.test.web.servlet.post
mockMvc.post("/hotels/{id}", 42) {
accept = MediaType.APPLICATION_JSON
}
您还可以执行文件上传请求,内部使用MockMultipartHttpServletRequest
,因此没有实际解析多部分请求。相反,您必须设置它类似于以下示例:
-
Java
-
Kotlin
mockMvc.perform(multipart("/doc").file("a1", "ABC".getBytes("UTF-8")));
import org.springframework.test.web.servlet.multipart
mockMvc.multipart("/doc") {
file("a1", "ABC".toByteArray(charset("UTF8")))
}
您可以按照URI模板样式指定查询参数,如下例所示:
-
Java
-
Kotlin
mockMvc.perform(get("/hotels?thing={thing}", "somewhere"));
mockMvc.get("/hotels?thing={thing}", "somewhere")
您还可以添加表示查询或表单参数的Servlet请求参数,如下例所示:
-
Java
-
Kotlin
mockMvc.perform(get("/hotels").param("thing", "somewhere"));
import org.springframework.test.web.servlet.get
mockMvc.get("/hotels") {
param("thing", "somewhere")
}
如果应用程序代码依赖Servlet请求参数并且不显式检查查询字符串(这在大多数情况下是最常见的情况),则使用哪种选项并不重要。但请记住,通过URI模板提供的查询参数会被解码,而通过param(…)
方法提供的请求参数预期已经被解码。
在大多数情况下,最好将上下文路径和Servlet路径排除在请求URI之外。如果必须使用完整的请求URI进行测试,请确保相应设置contextPath
和servletPath
,以便请求映射正常工作,如下例所示:
-
Java
-
Kotlin
mockMvc.perform(get("/app/main/hotels/{id}").contextPath("/app").servletPath("/main"))
import org.springframework.test.web.servlet.get
mockMvc.get("/app/main/hotels/{id}") {
contextPath = "/app"
servletPath = "/main"
}
在上面的示例中,每次执行请求时设置contextPath
和servletPath
会很麻烦。相反,您可以设置默认请求属性,如下例所示:
-
Java
-
Kotlin
class MyWebTests {
MockMvc mockMvc;
@BeforeEach
void setup() {
mockMvc = standaloneSetup(new AccountController())
.defaultRequest(get("/")
.contextPath("/app").servletPath("/main")
.accept(MediaType.APPLICATION_JSON)).build();
}
}
// 在{kotlin-issues}/KT-22208修复之前,无法在Kotlin中实现
上述属性会影响通过MockMvc
实例执行的每个请求。如果在给定请求上也指定了相同属性,则会覆盖默认值。这就是为什么默认请求中的HTTP方法和URI并不重要,因为它们必须在每个请求中指定。