定義預期
可以透過在執行請求後附加一個或多個 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 特定的方面,例如哪個控制器方法處理了請求,是否丟擲並處理了異常,Model 的內容是什麼,選擇了哪個檢視,添加了哪些 flash 屬性等等。它們還允許你檢查 Servlet 特定的方面,例如請求和會話屬性。
以下測試斷言繫結或驗證失敗
-
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://:8080/people"));
mockMvc.get("/people") {
accept(MediaType.APPLICATION_JSON)
}.andExpect {
jsonPath("$.links[?(@.rel == 'self')].href") {
value("https://: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://: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://:8080/people")
}
}