簡體   English   中英

Java Wiremock-在測試過程中模擬外部服務器

[英]Java Wiremock - mock external server during testing

假設應用程序依賴於外部服務器 http://otherserver.com上的REST服務。 為了進行測試,我想在JUnit環境中模擬外部Rest調用(通過Wiremock)。 啟動單獨的服務器會浪費時間,而且並不容易。 使用WiremockRule看起來是正確的方向。 由於可以使用Wiremock,因此創建模擬控制器並不是一種好方法。

例如get(“ http://otherserver.com/service3/ ”);

PS:當然,我知道我可以通過Mockito模擬REST調用。

使用Wiremock模擬localhost很容易。 如何使用該代碼模擬其他服務器和服務? 我復制了流行的Baeldung示例中的部分內容。

public class WireMockDemo {
    @Rule
    public WireMockRule wireMockRule = new WireMockRule();


    @Test
    public void wireMockTestJunitOtherServer() {
        try {
            // **this does not work...** 
            configureFor("otherserver.com", 8080);

            stubFor(get(urlPathMatching("/service2/.*"))
                    .willReturn(aResponse()
                            .withStatus(200)
                            .withHeader("Content-Type", "application/json")
                            .withBody("\"testing-library\": \"WireMock\"")));

            // Test via simple client
            CloseableHttpClient httpClient = HttpClients.createDefault();
            HttpGet request = new HttpGet("http://otherserver:8080/service2/test");
            HttpResponse httpResponse = httpClient.execute(request);
            String stringResponse = convertHttpResponseToString(httpResponse);
            System.out.println( "Response = " + stringResponse);

            // Test via JUnit
            verify(getRequestedFor(urlEqualTo("/service2/wiremock")));
            assertEquals(200, httpResponse.getStatusLine().getStatusCode());
            assertEquals("application/json", httpResponse.getFirstHeader("Content-Type").getValue());
            assertEquals("\"testing-library\": \"WireMock\"", stringResponse);
        } catch( Exception e) {
            e.printStackTrace();
        }
    }

    // Support methods
    private String convertHttpResponseToString(HttpResponse httpResponse) throws IOException {
        InputStream inputStream = httpResponse.getEntity().getContent();
        return convertInputStreamToString(inputStream);
    }
    private String convertInputStreamToString(InputStream inputStream) {
        Scanner scanner = new Scanner(inputStream, "UTF-8");
        String string = scanner.useDelimiter("\\Z").next();
        scanner.close();
        return string;
    }
}

您的應用程序代碼不應使用http://otherserver.com硬編碼,而應該是可配置的。 正常運行時,它應指向http://otherserver.com ;在測試模式下運行時,應指向http://localhost:<port> ,其中<port>是啟動Wiremock服務器的位置(最好動態啟動到避免端口沖突)

TL; DR:

你不能。

WireMock的作用是建立一個Jetty服務器,模擬您需要向其發送請求的遠程服務器。 但是,它不會更改hosts文件或DNS映射,並且會自動將對遠程服務器的實際請求“重定向”到localhost。 在測試中,您仍然需要將請求發送到localhost

如果使用Spring Boot,您可以做的是在maintest包中創建兩個application.yml文件(或另一個屬性文件),它們具有相同的鍵結構,但值在src/main/resources/application.yml是您請求的真實URL(例如http://example.com/api ),在src/test/resources/application.yml您將localhost/api放入了URL。


順便說一句,澄清MockMvcMockMvc不是用於模擬您的應用程序所依賴外部第三方服務器請求 ,而是用於發送到應用程序端點的請求 在MockMvc測試中,您的應用程序是接收請求的人,而在WireMock測試中,您的應用程序發送請求。

一些工作示例:

// configure static, class-level rule for all tests, like @BeforeClass.
// this launches a Jetty server with configurations
@ClassRule
public static WireMockClassRule classRule = new WireMockClassRule(options().
        port(80).httpsPort(443));

// Divide @ClassRule and @Rule,
// to bypass JUnit limitation of "@Rule cannot be static"
@Rule
public WireMockClassRule rule = classRule;


@Test
public void shouldReturnGivenJson() throws Exception {
    // stubFor() also works; givenThat() is more TDD-ish
    givenThat(post(urlEqualTo("/service2/test")) // <----- note here: without host name
            .willReturn(WireMock.aResponse()
                    .withStatus(HttpStatus.OK.value())
                    .withHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_UTF8_VALUE)
                    .withBody("{\"status\":\"up\"}")));
    // .... your connection here

我建議從urlEqualTo()開始,而不用正則表達式弄亂。 然后,您進入urlMatching()

另外,使用org.apache.http.util.EntityUtils從響應中獲取內容。 這是處理響應的官方內置方法。 並且,請使用ResponseHandler因為它將consume()響應而無需手動清理資源。

查看HttpClient文檔以獲取更多詳細信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM