对于最新的稳定版本,请使用 Spring Framework 7.0.6!spring-doc.cadn.net.cn

执行请求

本节展示如何单独使用MockMvc来执行请求并验证响应。 如果通过 WebTestClient 使用MockMvc,请参阅相应的 编写测试 部分。spring-doc.cadn.net.cn

要执行使用任何HTTP方法的请求,如下例所示:spring-doc.cadn.net.cn

// 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,因此实际上并不会解析多部分请求。相反,您需要将其设置为类似于以下示例:spring-doc.cadn.net.cn

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 模板样式中指定查询参数,如下例所示:spring-doc.cadn.net.cn

mockMvc.perform(get("/hotels?thing={thing}", "somewhere"));
mockMvc.get("/hotels?thing={thing}", "somewhere")

您还可以添加表示查询或表单参数的Servlet请求参数,如下例所示:spring-doc.cadn.net.cn

mockMvc.perform(get("/hotels").param("thing", "somewhere"));
import org.springframework.test.web.servlet.get

mockMvc.get("/hotels") {
	param("thing", "somewhere")
}

如果应用程序代码依赖于Servlet请求参数并且没有显式检查查询字符串(通常情况下),那么你使用哪个选项并不重要。但是,请记住,通过URI模板提供的查询参数会被解码,而通过param(…​)方法提供的请求参数则需要已经解码。spring-doc.cadn.net.cn

在大多数情况下,最好将上下文路径和Servlet路径排除在请求URI之外。如果你必须使用完整的请求URI进行测试,请确保相应地设置contextPathservletPath,以便请求映射能够正常工作,如下例所示:spring-doc.cadn.net.cn

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"
}

在前面的例子中,每次执行请求时设置 contextPathservletPath 会很繁琐。相反,您可以设置默认的请求属性,如下例所示:spring-doc.cadn.net.cn

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无关紧要,因为它们必须在每个请求中指定。spring-doc.cadn.net.cn