執行請求

本節說明如何單獨使用 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(…​) 方法提供的請求參數則預期已解碼。

在大多數情況下,最好將 context path 和 Servlet path 從請求 URI 中排除。如果您必須使用完整的請求 URI 進行測試,請務必相應地設定 contextPathservletPath,以便請求對應正常運作,如下列範例所示

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

在先前的範例中,為每個執行的請求設定 contextPathservletPath 會很麻煩。相反地,您可以設定預設請求屬性,如下列範例所示

  • 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 {kotlin-issues}/KT-22208 is fixed

先前的屬性會影響透過 MockMvc 實例執行的每個請求。如果相同的屬性也在給定的請求上指定,則它會覆寫預設值。這就是為什麼預設請求中的 HTTP 方法和 URI 無關緊要的原因,因為它們必須在每個請求上指定。