【问题标题】:Unit testing Vertx - java.util.concurrent.TimeoutException单元测试 Vertx - java.util.concurrent.TimeoutException
【发布时间】:2017-06-09 11:08:28
【问题描述】:

我正在尝试对来自 vertx WebClient uing VertxUnitRunner 和 vertx 的 RXified 版本的 http 调用进行单元测试。

问题是我的单元测试总是因超时异常而失败。是否有不同的方法来对WebClient http 调用进行单元测试?以下是我的代码:

import io.vertx.core.AsyncResult;
import io.vertx.core.http.HttpClientOptions;
import io.vertx.core.http.HttpServerOptions;
import io.vertx.ext.unit.TestContext;
import io.vertx.ext.unit.junit.VertxUnitRunner;
import io.vertx.rxjava.core.Vertx;
import io.vertx.rxjava.core.buffer.Buffer;
import io.vertx.rxjava.core.http.HttpServer;
import io.vertx.rxjava.ext.web.client.HttpResponse;
import io.vertx.rxjava.ext.web.client.WebClient;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import rx.Single;


@RunWith(VertxUnitRunner.class)
public class MyVertxTest {

    private Vertx vertx;
    private WebClient client;

    @Before
    public void setUp() throws Exception {
        vertx = Vertx.vertx();
    }

    @Test
    public void testGetContactDetails(TestContext context) {

        System.out.println("start");
        long start = System.currentTimeMillis();
        HttpServer server = vertx.createHttpServer(new HttpServerOptions().setPort(TEST_SERVER_PORT));

        server.requestStream().handler(req -> {
            req.response().setChunked(true).write("foo bar").end();
        });

        System.out.println("created server");

        try {
            server.listen(9000, "localhost", (AsyncResult<HttpServer> ar) -> {

                client = WebClient.wrap(vertx.createHttpClient(new HttpClientOptions()));

                System.out.println("created client");

                Single<HttpResponse<Buffer>> single = client
                        .get(9000, "localhost", "/foo")
                        .rxSend();

                single.subscribe(s -> {
                    System.out.println("inside subscribe");
                    context.assertEquals("foo bar", s.bodyAsString());
                }, e -> {
                    context.fail(e);
                });
            });

            context.async().await();
            System.out.println("total time : " + (System.currentTimeMillis() - start / 1000)+" seconds);

        } catch (Exception e) {
            context.fail(e);
        } finally {
            server.close();
        }
    }
}

测试总是因为 120 秒后超时而失败

输出

start
created server
created client
inside subscribe
total time : 120

java.util.concurrent.TimeoutException
    at io.vertx.ext.unit.impl.TestContextImpl$Step.lambda$run$0(TestContextImpl.java:112)
    at java.lang.Thread.run(Thread.java:745)

【问题讨论】:

    标签: unit-testing rx-java vert.x vertx-httpclient


    【解决方案1】:

    因为您对async 的使用是错误的。它类似于 java CountDownLatch。在docs中有描述

    所以正确的用法是:

            Async async = context.async(); //here
    
            server.listen(9000, "localhost", (AsyncResult<HttpServer> ar) -> {
    
                client = WebClient.wrap(vertx.createHttpClient(new HttpClientOptions()));
    
                System.out.println("created client");
    
                Single<HttpResponse<Buffer>> single = client
                  .get(9000, "localhost", "/foo")
                  .rxSend().subscribeOn(Schedulers.io());
    
                single.subscribe(s -> {
                    System.out.println("inside subscribe");
                    context.assertEquals("foo bar", s.bodyAsString());
                    async.complete(); //here
                }, e -> {
                    context.fail(e);
                });
            });
    
            async.awaitSuccess();
    

    你也可以让你的代码阻塞以避免异步测试:

            Single<HttpServer> obs = server.rxListen(9000, "localhost");
            obs.toBlocking().value(); //here
    
            client = WebClient.wrap(vertx.createHttpClient(new HttpClientOptions()));
    
            System.out.println("created client");
    
            Single<HttpResponse<Buffer>> single = client
              .get(9000, "localhost", "/foo")
              .rxSend().subscribeOn(Schedulers.io());
    
            Assert.assertEquals(single.toBlocking().value().bodyAsString(), "foo bar"); //here
    

    【讨论】:

      【解决方案2】:

      您可以尝试添加超时规则

      @规则

      公共超时 timeoutRule = Timeout.seconds(3600);

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-29
        • 1970-01-01
        • 1970-01-01
        • 2020-02-23
        • 1970-01-01
        相关资源
        最近更新 更多