|
对于最新稳定版本,请使用 Spring Framework 7.0.6! |
执行请求
本节展示了如何单独使用 MockMvc 来执行请求并验证响应。
如果通过 WebTestClient 使用 MockMvc,请参阅相应的
编写测试 章节。
执行使用任意 HTTP 方法的请求,如下例所示:
-
Java
-
Kotlin
// static import of 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,因此不会实际解析 multipart 请求。相反,你需要按如下示例进行设置:
-
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(…) 方法提供的请求参数则应已被解码。
在大多数情况下,最好从请求 URI 中省略上下文路径和 Servlet 路径。如果你必须使用完整的请求 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();
}
}
// Not possible in Kotlin until https://youtrack.jetbrains.com/issue/KT-22208 is fixed
上述属性会影响通过 MockMvc 实例执行的每个请求。
如果在某个具体请求中也指定了相同的属性,则会覆盖默认值。
这就是为什么默认请求中的 HTTP 方法和 URI 并不重要,因为它们必须在每个请求中明确指定。