測試用戶端應用程式
您可以使用用戶端測試來測試在內部使用 RestTemplate
的程式碼。其概念是宣告預期的請求並提供「存根」回應,以便您可以專注於隔離測試程式碼(即,無需執行伺服器)。以下範例展示了如何執行此操作
-
Java
-
Kotlin
RestTemplate restTemplate = new RestTemplate();
MockRestServiceServer mockServer = MockRestServiceServer.bindTo(restTemplate).build();
mockServer.expect(requestTo("/greeting")).andRespond(withSuccess());
// Test code that uses the above RestTemplate ...
mockServer.verify();
val restTemplate = RestTemplate()
val mockServer = MockRestServiceServer.bindTo(restTemplate).build()
mockServer.expect(requestTo("/greeting")).andRespond(withSuccess())
// Test code that uses the above RestTemplate ...
mockServer.verify()
在上述範例中,MockRestServiceServer
(用戶端 REST 測試的中心類別)使用自訂 ClientHttpRequestFactory
組態 RestTemplate
,該工廠會根據期望斷言實際請求並傳回「存根」回應。在本例中,我們預期對 /greeting
的請求,並希望傳回具有 text/plain
內容的 200 回應。我們可以根據需要定義其他預期的請求和存根回應。當我們定義預期的請求和存根回應時,RestTemplate
可以像往常一樣在用戶端程式碼中使用。在測試結束時,可以使用 mockServer.verify()
來驗證是否已滿足所有期望。
預設情況下,請求會按照宣告期望的順序預期。您可以在建置伺服器時設定 ignoreExpectOrder
選項,在這種情況下,會檢查所有期望(依序)以尋找給定請求的相符項。這表示允許請求以任何順序進入。以下範例使用 ignoreExpectOrder
-
Java
-
Kotlin
server = MockRestServiceServer.bindTo(restTemplate).ignoreExpectOrder(true).build();
server = MockRestServiceServer.bindTo(restTemplate).ignoreExpectOrder(true).build()
即使預設情況下請求是無序的,每個請求也僅允許執行一次。expect
方法提供了一個多載變體,它接受一個 ExpectedCount
引數,該引數指定計數範圍(例如,once
、manyTimes
、max
、min
、between
等)。以下範例使用 times
-
Java
-
Kotlin
RestTemplate restTemplate = new RestTemplate();
MockRestServiceServer mockServer = MockRestServiceServer.bindTo(restTemplate).build();
mockServer.expect(times(2), requestTo("/something")).andRespond(withSuccess());
mockServer.expect(times(3), requestTo("/somewhere")).andRespond(withSuccess());
// ...
mockServer.verify();
val restTemplate = RestTemplate()
val mockServer = MockRestServiceServer.bindTo(restTemplate).build()
mockServer.expect(times(2), requestTo("/something")).andRespond(withSuccess())
mockServer.expect(times(3), requestTo("/somewhere")).andRespond(withSuccess())
// ...
mockServer.verify()
請注意,當未設定 ignoreExpectOrder
(預設值),因此請求預期按宣告順序排列時,該順序僅適用於任何預期請求的第一個。例如,如果 "/something" 預期兩次,然後 "/somewhere" 預期三次,則在請求 "/somewhere" 之前應該先請求 "/something",但除此之外,後續的 "/something" 和 "/somewhere" 請求可以隨時到達。
作為上述所有方法的替代方案,用戶端測試支援還提供了一個 ClientHttpRequestFactory
實作,您可以將其組態到 RestTemplate
中,以將其繫結到 MockMvc
實例。這允許使用實際的伺服器端邏輯處理請求,但無需執行伺服器。以下範例展示了如何執行此操作
-
Java
-
Kotlin
MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
this.restTemplate = new RestTemplate(new MockMvcClientHttpRequestFactory(mockMvc));
// Test code that uses the above RestTemplate ...
val mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build()
restTemplate = RestTemplate(MockMvcClientHttpRequestFactory(mockMvc))
// Test code that uses the above RestTemplate ...
在某些情況下,可能需要執行對遠端服務的實際呼叫,而不是模擬回應。以下範例展示了如何透過 ExecutingResponseCreator
執行此操作
-
Java
-
Kotlin
RestTemplate restTemplate = new RestTemplate();
// Create ExecutingResponseCreator with the original request factory
ExecutingResponseCreator withActualResponse = new ExecutingResponseCreator(restTemplate.getRequestFactory());
MockRestServiceServer mockServer = MockRestServiceServer.bindTo(restTemplate).build();
mockServer.expect(requestTo("/profile")).andRespond(withSuccess());
mockServer.expect(requestTo("/quoteOfTheDay")).andRespond(withActualResponse);
// Test code that uses the above RestTemplate ...
mockServer.verify();
val restTemplate = RestTemplate()
// Create ExecutingResponseCreator with the original request factory
val withActualResponse = new ExecutingResponseCreator(restTemplate.getRequestFactory())
val mockServer = MockRestServiceServer.bindTo(restTemplate).build()
mockServer.expect(requestTo("/profile")).andRespond(withSuccess())
mockServer.expect(requestTo("/quoteOfTheDay")).andRespond(withActualResponse)
// Test code that uses the above RestTemplate ...
mockServer.verify()
在上述範例中,我們使用 RestTemplate
中的 ClientHttpRequestFactory
在 MockRestServiceServer
將其替換為模擬回應的不同工廠之前建立 ExecutingResponseCreator
。然後,我們使用兩種回應類型定義期望
-
針對
/profile
端點的存根200
回應(不會執行實際請求) -
透過呼叫
/quoteOfTheDay
端點取得的回應
在第二種情況下,請求會透過先前擷取的 ClientHttpRequestFactory
執行。這會產生一個回應,該回應例如可能來自實際的遠端伺服器,具體取決於 RestTemplate
最初的組態方式。
靜態匯入
與伺服器端測試一樣,用戶端測試的 Fluent API 需要一些靜態匯入。這些靜態匯入很容易透過搜尋 MockRest*
找到。Eclipse 使用者應在 Eclipse 偏好設定的 Java → 編輯器 → 內容輔助 → 我的最愛下,將 MockRestRequestMatchers.*
和 MockRestResponseCreators.*
新增為「最愛的靜態成員」。這允許在輸入靜態方法名稱的第一個字元後使用內容輔助。其他 IDE(例如 IntelliJ)可能不需要任何額外的組態。檢查是否支援靜態成員的程式碼完成。
用戶端 REST 測試的更多範例
Spring MVC Test 自己的測試包括 用戶端 REST 測試的範例測試。