定義期望

您可以透過在執行請求後附加一或多個 andExpect(..) 呼叫來定義期望,如下列範例所示。只要有一個期望失敗,就不會再斷言其他期望。

  • Java

  • Kotlin

// static import of MockMvcRequestBuilders.* and MockMvcResultMatchers.*

mockMvc.perform(get("/accounts/1")).andExpect(status().isOk());
import org.springframework.test.web.servlet.get

mockMvc.get("/accounts/1").andExpect {
	status { isOk() }
}

您可以透過在執行請求後附加 andExpectAll(..) 來定義多個期望,如下列範例所示。與 andExpect(..) 相反,andExpectAll(..) 保證所有提供的期望都會被斷言,並且所有失敗都會被追蹤和回報。

  • Java

  • Kotlin

// static import of MockMvcRequestBuilders.* and MockMvcResultMatchers.*

mockMvc.perform(get("/accounts/1")).andExpectAll(
	status().isOk(),
	content().contentType("application/json;charset=UTF-8"));
import org.springframework.test.web.servlet.get

mockMvc.get("/accounts/1").andExpectAll {
	status { isOk() }
	content { contentType(APPLICATION_JSON) }
}

MockMvcResultMatchers.* 提供了許多期望,其中一些期望更深入地巢狀包含更詳細的期望。

期望分為兩大類。第一類斷言驗證回應的屬性(例如,回應狀態、標頭和內容)。這些是要斷言的最重要結果。

第二類斷言超越了回應。這些斷言可讓您檢查 Spring MVC 特定的方面,例如哪個控制器方法處理了請求、是否引發並處理了例外、模型的內容是什麼、選取了哪個檢視、新增了哪些 Flash 屬性等等。它們還可讓您檢查 Servlet 特定的方面,例如請求和 Session 屬性。

以下測試斷言繫結或驗證失敗

  • Java

  • Kotlin

mockMvc.perform(post("/persons"))
	.andExpect(status().isOk())
	.andExpect(model().attributeHasErrors("person"));
import org.springframework.test.web.servlet.post

mockMvc.post("/persons").andExpect {
	status { isOk() }
	model {
		attributeHasErrors("person")
	}
}

許多時候,在編寫測試時,轉儲已執行請求的結果非常有用。您可以透過以下方式執行此操作,其中 print() 是從 MockMvcResultHandlers 靜態匯入的

  • Java

  • Kotlin

mockMvc.perform(post("/persons"))
	.andDo(print())
	.andExpect(status().isOk())
	.andExpect(model().attributeHasErrors("person"));
import org.springframework.test.web.servlet.post

mockMvc.post("/persons").andDo {
		print()
	}.andExpect {
		status { isOk() }
		model {
			attributeHasErrors("person")
		}
	}

只要請求處理不會導致未處理的例外,print() 方法就會將所有可用的結果資料列印到 System.out。還有一個 log() 方法和兩個額外的 print() 方法變體,一個接受 OutputStream,另一個接受 Writer。例如,調用 print(System.err) 會將結果資料列印到 System.err,而調用 print(myWriter) 則會將結果資料列印到自訂 Writer。如果您希望記錄結果資料而不是列印,則可以調用 log() 方法,該方法會將結果資料記錄為 org.springframework.test.web.servlet.result 記錄類別下的單個 DEBUG 訊息。

在某些情況下,您可能想要直接存取結果並驗證其他方式無法驗證的內容。這可以透過在所有其他期望之後附加 .andReturn() 來實現,如下列範例所示

  • Java

  • Kotlin

MvcResult mvcResult = mockMvc.perform(post("/persons")).andExpect(status().isOk()).andReturn();
// ...
var mvcResult = mockMvc.post("/persons").andExpect { status { isOk() } }.andReturn()
// ...

如果所有測試都重複相同的期望,您可以在建構 MockMvc 實例時一次設定通用期望,如下列範例所示

  • Java

  • Kotlin

standaloneSetup(new SimpleController())
	.alwaysExpect(status().isOk())
	.alwaysExpect(content().contentType("application/json;charset=UTF-8"))
	.build()
// Not possible in Kotlin until {kotlin-issues}/KT-22208 is fixed

請注意,通用期望始終會被套用,並且無法在不建立單獨的 MockMvc 實例的情況下覆寫。

當 JSON 回應內容包含使用 Spring HATEOAS 建立的超媒體連結時,您可以使用 JsonPath 運算式來驗證結果連結,如下列範例所示

  • Java

  • Kotlin

mockMvc.perform(get("/people").accept(MediaType.APPLICATION_JSON))
	.andExpect(jsonPath("$.links[?(@.rel == 'self')].href").value("https://127.0.0.1:8080/people"));
mockMvc.get("/people") {
	accept(MediaType.APPLICATION_JSON)
}.andExpect {
	jsonPath("$.links[?(@.rel == 'self')].href") {
		value("https://127.0.0.1:8080/people")
	}
}

當 XML 回應內容包含使用 Spring HATEOAS 建立的超媒體連結時,您可以使用 XPath 運算式來驗證結果連結

  • Java

  • Kotlin

Map<String, String> ns = Collections.singletonMap("ns", "http://www.w3.org/2005/Atom");
mockMvc.perform(get("/handle").accept(MediaType.APPLICATION_XML))
	.andExpect(xpath("/person/ns:link[@rel='self']/@href", ns).string("https://127.0.0.1:8080/people"));
val ns = mapOf("ns" to "http://www.w3.org/2005/Atom")
mockMvc.get("/handle") {
	accept(MediaType.APPLICATION_XML)
}.andExpect {
	xpath("/person/ns:link[@rel='self']/@href", ns) {
		string("https://127.0.0.1:8080/people")
	}
}