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

执行请求

本节介绍如何单独使用 MockMvc 来执行请求和验证响应。 如果通过WebTestClient请参阅相应的 编写测试 部分。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
}

You can also perform file upload requests that internally use MockMultipartHttpServletRequest so that there is no actual parsing of a multipart request. Rather, you have to set it up to be similar to the following example: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")))
}

You can specify query parameters in URI template style, as the following example shows:spring-doc.cadn.net.cn

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

You can also add Servlet request parameters that represent either query or form parameters, as the following example shows: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")
}

If application code relies on Servlet request parameters and does not check the query string explicitly (as is most often the case), it does not matter which option you use. Keep in mind, however, that query parameters provided with the URI template are decoded while request parameters provided through the param(…​) method are expected to already be decoded.spring-doc.cadn.net.cn

In most cases, it is preferable to leave the context path and the Servlet path out of the request URI. If you must test with the full request URI, be sure to set the contextPath and servletPath accordingly so that request mappings work, as the following example shows: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"
}

In the preceding example, it would be cumbersome to set the contextPath and servletPath with every performed request. Instead, you can set up default request properties, as the following example shows: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 {kotlin-issues}/KT-22208 is fixed

The preceding properties affect every request performed through the MockMvc instance. If the same property is also specified on a given request, it overrides the default value. That is why the HTTP method and URI in the default request do not matter, since they must be specified on every request.spring-doc.cadn.net.cn