![](/img/trans.png)
[英]Stress testing with an external API server in Java Spring - mock response?
[英]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,您可以做的是在main
和test
包中創建兩個application.yml
文件(或另一個屬性文件),它們具有相同的鍵結構,但值在src/main/resources/application.yml
是您請求的真實URL(例如http://example.com/api
),在src/test/resources/application.yml
您將localhost/api
放入了URL。
順便說一句,澄清MockMvc
, MockMvc
不是用於模擬您的應用程序所依賴的外部第三方服務器請求 ,而是用於發送到應用程序端點的請求 。 在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.