日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用WireMock进行更好的集成测试

發布時間:2023/12/3 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用WireMock进行更好的集成测试 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

無論您是遵循傳統的測試金字塔還是采用諸如“ 測試蜂窩”這樣的較新方法,都應該在開發過程中的某個時候開始編寫集成測試。

您可以編寫不同類型的集成測試。 從持久性測試開始,您可以檢查組件之間的交互,也可以模擬調用外部服務。 本文將討論后一種情況。 在談論WireMock之前,讓我們從一個激勵性的例子開始。

ChuckNorrisFact服務

完整的示例可以在GitHub上找到 。

在以前的博客文章中,您可能已經看到我使用Chuck Norris事實API 。 該API將為我們提供實現所依賴的另一項服務的示例。 我們有一個簡單的ChuckNorrisFactController作為用于手動測試的API。 “業務”類旁邊是ChuckNorrisService ,用于調用外部API。 它使用Spring的RestTemplate 。 沒什么特別的。 我多次看到的是模擬RestTemplate并返回一些預先確定的答案的測試。 該實現可能如下所示:

@Service public class ChuckNorrisService{ ... public ChuckNorrisFact retrieveFact() { ResponseEntity<ChuckNorrisFactResponse> response = restTemplate.getForEntity(url, ChuckNorrisFactResponse. class ); return Optional.ofNullable(response.getBody()).map(ChuckNorrisFactResponse::getFact).orElse(BACKUP_FACT); } ... }

在檢查成功案例的常規單元測試旁邊,將至少有一項覆蓋錯誤案例的測試,即4xx或5xx狀態代碼:

@Test public void shouldReturnBackupFactInCaseOfError() { String url = " http://localhost:8080 " ; RestTemplate mockTemplate = mock(RestTemplate. class ); ResponseEntity<ChuckNorrisFactResponse> responseEntity = new ResponseEntity<>(HttpStatus.SERVICE_UNAVAILABLE); when(mockTemplate.getForEntity(url, ChuckNorrisFactResponse. class )).thenReturn(responseEntity); var service = new ChuckNorrisService(mockTemplate, url); ChuckNorrisFact retrieved = service.retrieveFact(); assertThat(retrieved).isEqualTo(ChuckNorrisService.BACKUP_FACT); }

看起來還不錯吧? 響應實體返回503錯誤代碼,我們的服務不會崩潰。 所有測試都是綠色的,我們可以部署我們的應用程序。

不幸的是,Spring的RestTemplate不能這樣工作。 getForEntity的方法簽名為我們提供了一個非常小的提示。 它指出throws RestClientException 。 這就是模擬的RestTemplate與實際實現不同的地方。 我們將永遠不會收到帶有4xx或5xx狀態代碼的ResponseEntity 。 RestTemplate將拋出一個子類 RestClientException 。 通過查看類的層次結構,我們可以對可能拋出的結果有一個很好的印象:


因此,讓我們看看如何使這項測試更好。

WireMock進行救援

WireMock通過啟動模擬服務器并返回將其配置為返回的答案來模擬Web服務。 得益于出色的DSL,它很容易集成到您的測試中,并且模擬請求也很簡單。

對于JUnit 4,有一個WireMockRule可以幫助啟動停止服務器。 對于JUnit 5,您必須自己做。 當您檢查示例項目時,您可以找到ChuckNorrisServiceIntegrationTest 。 這是基于JUnit 4的SpringBoot測試。讓我們看一下。 最重要的部分是ClassRule :

@ClassRule public static WireMockRule wireMockRule = new WireMockRule();

如前所述,這將啟動和停止WireMock服務器。 您也可以使用常規Rule來為每個測試啟動和停止服務器。 對于我們的測試,這不是必需的。

接下來,您可以看到幾種configureWireMockFor...方法。 這些包含WireMock何時返回答案的說明。 將WireMock配置分為幾種方法并從測試中調用它們是我使用WireMock的方法。 當然,您可以在@Before方法中設置所有可能的請求。 對于成功案例,我們這樣做:

public void configureWireMockForOkResponse(ChuckNorrisFact fact) JsonProcessingException { configureWireMockForOkResponse(ChuckNorrisFact fact) throws JsonProcessingException { ChuckNorrisFactResponse chuckNorrisFactResponse = new ChuckNorrisFactResponse chuckNorrisFactResponse = ChuckNorrisFactResponse( "success" , fact); stubFor(get(urlEqualTo( "/jokes/random" )) .willReturn(okJson(OBJECT_MAPPER.writeValueAsString(chuckNorrisFactResponse)))); }

所有方法都是從com.github.tomakehurst.wiremock.client.WireMock靜態com.github.tomakehurst.wiremock.client.WireMock 。 如您所見,我們將HTTP GET存入路徑/jokes/random并返回一個JSON對象。 的
okJson()方法只是JSON內容的200個響應的簡寫。 對于錯誤情況,代碼甚至更簡單:

private void configureWireMockForErrorResponse() { stubFor(get(urlEqualTo( "/jokes/random" )) .willReturn(serverError())); }

如您所見,DSL使閱讀說明變得容易。

將WireMock放置在適當的位置,我們可以看到我們先前的實現不起作用,因為RestTemplate引發了異常。 因此,我們必須調整代碼:

public ChuckNorrisFact retrieveFact() { try { ResponseEntity<ChuckNorrisFactResponse> response = restTemplate.getForEntity(url, ChuckNorrisFactResponse. class ); return Optional.ofNullable(response.getBody()).map(ChuckNorrisFactResponse::getFact).orElse(BACKUP_FACT); } catch (HttpStatusCodeException e){ return BACKUP_FACT; } }

這已經涵蓋了WireMock的基本用例。 配置請求的答案,執行測試,檢查結果。 就這么簡單。

但是,在云環境中運行測試時,通常會遇到一個問題。 讓我們看看我們能做什么。

動態端口上的WireMock

您可能已經注意到,項目中的集成測試包含一個
ApplicationContextInitializer類及其@TestPropertySource批注將覆蓋實際API的URL。 那是因為我想在隨機端口上啟動WireMock。 當然,您可以為WireMock配置一個固定端口,并在測試中將此端口用作硬編碼值。 但是,如果您的測試在某些云提供商的基礎架構上運行,則無法確定該端口是否可用。 因此,我認為隨機端口更好。
不過,在Spring應用程序中使用屬性時,我們必須以某種方式將隨機端口傳遞給我們的服務。 或者,如您在示例中看到的那樣,覆蓋URL。 這就是為什么我們使用ApplicationContextInitializer 。 我們將動態分配的端口添加到應用程序上下文中,然后可以使用屬性來引用它 ${wiremock.port} 。 這里唯一的缺點是我們現在必須使用ClassRule。 否則,我們無法在初始化Spring應用程序之前訪問端口。 解決了此問題后,讓我們看一下涉及HTTP調用的一個常見問題。

超時時間

WireMock提供了更多的響應可能性,而不僅僅是對GET請求的簡單答復。 經常被遺忘的另一個測試案例是測試超時。 開發人員往往會忘記在RestTemplate甚至URLConnections上設置超時。 如果沒有超時,則兩者都將等待無限量的時間來進行響應。 在最好的情況下,您不會注意到,在最壞的情況下,所有線程都將等待永遠不會到達的響應。

因此,我們應該添加一個模擬超時的測試。 當然,我們也可以使用Mockito模擬來創建延遲,但是在這種情況下,我們將再次猜測RestTemplate的行為。 使用WireMock模擬延遲非常簡單:

private void configureWireMockForSlowResponse() throws JsonProcessingException { ChuckNorrisFactResponse chuckNorrisFactResponse = new ChuckNorrisFactResponse chuckNorrisFactResponse = ChuckNorrisFactResponse( "success" , new ChuckNorrisFact(1L, "" )); stubFor(get(urlEqualTo( "/jokes/random" )) .willReturn( okJson(OBJECT_MAPPER.writeValueAsString(chuckNorrisFactResponse)) .withFixedDelay(( int ) Duration.ofSeconds(10L).toMillis()))); }

withFixedDelay()需要一個表示毫秒的int值。 我更喜歡使用Duration或至少一個表示該參數表示毫秒的常量,而不必每次都讀取JavaDoc。

在RestTemplate上設置超時并添加響應緩慢的測試后,我們可以看到RestTemplate拋出ResourceAccessException 。 因此,我們可以調整catch塊以捕獲此異常和HttpStatusCodeException或者僅捕獲兩者的超類:

public ChuckNorrisFact retrieveFact() { try { ResponseEntity<ChuckNorrisFactResponse> response = restTemplate.getForEntity(url, ChuckNorrisFactResponse. class ); return Optional.ofNullable(response.getBody()).map(ChuckNorrisFactResponse::getFact).orElse(BACKUP_FACT); } catch (RestClientException e){ return BACKUP_FACT; } }

現在,我們已經很好地介紹了執行HTTP請求時最常見的情況,并且可以確定我們正在測試接近真實條件的條件。

為什么不飛翔?

HTTP集成測試的另一個選擇是Hoverfly 。 它的工作原理類似于WireMock,但我更喜歡后者。 原因是在運行包含瀏覽器的端到端測試時,WireMock也非常有用。 Hoverfly(至少是Java庫)受JVM代理的限制。 這可能使它比WireMock更快,但是當例如某些JavaScript代碼開始起作用時,它根本不起作用。 當您的瀏覽器代碼也直接調用其他一些服務時,WireMock啟動Web服務器這一事實非常有用。 然后,您也可以使用WireMock來模擬它們,并編寫例如Selenium測試。

結論

我希望本文可以向您展示兩件事:

  • 集成測試的重要性
  • WireMock非常好
  • 當然,這兩個主題都可以填滿更多文章。 盡管如此,我還是想讓您了解如何使用WireMock及其功能。 隨時檢查他們的文檔,然后嘗試更多其他事情。 例如,也可以使用WireMock測試身份驗證。

    翻譯自: https://www.javacodegeeks.com/2019/11/better-integration-tests-with-wiremock.html

    總結

    以上是生活随笔為你收集整理的使用WireMock进行更好的集成测试的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。