【问题标题】:Vertx HttpClientRequest handler behavior testVertx HttpClientRequest 处理程序行为测试
【发布时间】:2019-07-08 17:34:11
【问题描述】:

我有一个创建 HttpClientRequest 实例并将 Handler 关联到它的方法。

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
          }
        });}

客户端请求是针对第 3 方服务的。我应该如何编写单元测试来调用处理程序的不同子句?我正在使用 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

【问题讨论】:

  • 显示到目前为止您尝试过的内容
  • @Coder 我的错,添加了目前写的测试用例。

标签: java unit-testing mockito vert.x


【解决方案1】:

我建议使用 Wiremock 模拟该 3rd 方服务的响应:

@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();
        });
    }

}

【讨论】:

  • 我更倾向于模仿 HttpClientRequest 执行流程。
  • 抱歉,这种方法无法帮助您
【解决方案2】:

我能够使用 ArgumentCaptor 完成它。

这是有助于实现上述目标的一段代码(上述测试的一部分)。

声明 ArgumentCaptor:

 @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);
  });

解释:ArgumentCaptor 捕获执行流程,然后可以使用所需的参数手动触发进一步的执行。它仅适用于Mockito.verify

【讨论】:

    猜你喜欢
    • 2017-08-05
    • 2020-07-22
    • 1970-01-01
    • 2020-02-23
    • 1970-01-01
    • 2023-04-10
    • 2018-03-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多