我有一种创建httpclientRequest实例并将处理程序关联的方法。
public void sendRequest(String requestId, File file, Message<A> message) {
final HttpClientRequest request = getHttpClientRequest();
request.putHeader(HttpHeaders.CONTENT_TYPE.toString(), FORM_DATA);
request.putHeader(HttpHeaders.ACCEPT.toString(), APPNEXUS_JSON_HEADER);
request.putHeader(HttpHeaders.CONTENT_TRANSFER_ENCODING.toString(), "binary");
final Buffer buffer = this.getBody(file.getAbsolutePath());
request.putHeader(HttpHeaders.CONTENT_LENGTH.toString(), String.valueOf(buffer.length()));
request.handler(httpClientResponse -> {
switch (httpClientResponse.statusCode()) {
case Status.SC_OK:
httpClientResponse.bodyHandler(body -> {
// Do something
});
break;
case Status.TOO_MANY_REQUESTS:
// Do something
break;
default:
// Do something
}
});}
客户请求是第三方服务。我应该如何编写单元测试来调用处理程序的不同条款?我正在使用Mockito嘲笑任务。
测试我到目前为止写过的,
public void testSomething (TestContext testContext) { final Async async = testContext.async(); Mockito.when(httpClientRequest.exceptionHandler(Mockito.any())).thenReturn(httpClientRequest); Mockito.when(httpClientRequest.putHeader(Mockito.anyString(), Mockito.anyString())).thenReturn(httpClientRequest); Mockito.doAnswer(invocation -> { return httpClientResponse; }).when(httpClientRequest).end(Mockito.any(Buffer.class)); Mockito.when(routingContext.response()).thenReturn(httpServerResponse); Mockito.when(routingContext.statusCode()).thenReturn(200); Mockito.when(routingContext.getBody()).thenReturn(buffer); JsonObject jsonObject = Mockito.mock(JsonObject.class); Mockito.when(buffer.toJsonObject()).thenReturn(jsonObject); Mockito.when(jsonObject.mapTo(Mockito.any())).thenReturn(appnexusBulkSyncResponse); Mockito.when(file.getAbsolutePath()).thenReturn("testpath"); String requestId = "req-1"; JsonObject uploadRequest = new JsonObject(); uploadRequest.put("requestId", requestId); vertx.eventBus().consumer("test-bus", (Message<A> message) -> { syncClient.sendRequest(requestId, file, message); }); vertx.eventBus().send("test-bus", uploadRequest, event -> { async.complete(); }); async.await(TIMEOUT); }
您可以假设所有变量均根据需要模拟。我希望测试在sendRequest
方法中调用request.handler
。验证了整个流量最高为request.end
。
我能够使用参数captor完成。
这是有助于实现上述代码的一部分(上述测试的一部分(。
声明参数captor:
@Captor private ArgumentCaptor<Handler<HttpClientResponse>> requestCaptor;
在测试中使用绑架者:
vertx.eventBus().consumer("test-bus", (Message<A> message) -> { syncClient.sendRequest(requestId, file, message); Mockito.verify(httpClientRequest, Mockito.times(1)).handler(requestCaptor.capture()); Handler<HttpClientResponse> httpClientResponseHandler = requestCaptor.getValue(); httpClientResponseHandler.handle(httpClientResponse); });
说明:参数captor捕获执行流,然后可以通过所需的参数手动触发进一步的执行。它仅适用于Mockito.verify
。
我建议用wiremock模拟该第三方服务的响应:
@RunWith(VertxUnitRunner.class)
public class MyTestClass {
private static WireMockServer wiremock;
private Vertx vertx;
@BeforeClass
public static void init() {
wiremock = new WireMockServer(host, port); //configure host and port
wiremock.start();
}
@AfterClass
public static void cleanup() {
wiremock.stop();
}
@Before
public void setup(TestContext ctx){
//init vertx
Async async = testContext.async();
vertx = Vertx.vertx();
...
async.complete();
}
@Test
public void mytest(TestContext testContext){
Async async = testContext.async();
stubFor(get(urlPathMatching("/.*"))
.willReturn(aResponse()
.withStatus(200)
.withHeader("Content-Type", "application/json")
.withBody("{}")));
HttpClient client = vertx.createHttpClient(...)
client.getNow("/some-uri", response -> {
//check response
async.complete();
});
}
}