【问题标题】:Waiting for an http response to return from vertx WebClient using CountDownLatch使用 CountDownLatch 等待从 vertx WebClient 返回的 http 响应
【发布时间】:2019-05-07 09:08:09
【问题描述】:

我正在为一些休息 api 编写一些测试,我有一个调度程序将我的休息请求从 vertx 发送到 WebClient,在某些情况下,我想等待来自休息 api 的响应返回,然后我才能继续进一步我的断言,调度请求的代码被包装在其他类中,所以我不是直接从测试发出这些请求,我的请求调度程序有 2 个实现,一个用于生产,一个用于测试,测试调度程序看起来像这样:

public class TestRequestDispatcher extends AbstractRequestDispatcher {

    @Override
    protected void dispatchRequest(ServerRequest request, ServerRequestEventFactory requestEventFactory) {

        request.getSender()
                .send(request,
                        new ServerRequestCallBack() {

                            @Override
                            public <T> void onSuccess(T response) {
                                requestEventFactory.makeSuccess(request, response).fire();
                            }

                            @Override
                            public void onFailure(FailedResponseBean failedResponse) {
                                requestEventFactory.makeFailed(request, failedResponse).fire();
                            }
                        });
    }
}

然后这应该调用一些构建 WebClient 的代码并调用其 send 方法将请求发送到服务器。

为了等待回复,我决定使用CountDownLatch 并将我的代码修改为以下内容

public class TestRequestDispatcher extends AbstractRequestDispatcher {

    @Override
    protected void dispatchRequest(ServerRequest request, ServerRequestEventFactory requestEventFactory) {

        CountDownLatch requestWait = new CountDownLatch(1);

        request.getSender()
                .send(request,
                        new ServerRequestCallBack() {

                            @Override
                            public <T> void onSuccess(T response) {
                                requestWait.countDown();
                                requestEventFactory.makeSuccess(request, response).fire();
                            }

                            @Override
                            public void onFailure(FailedResponseBean failedResponse) {
                                requestWait.countDown();
                                requestEventFactory.makeFailed(request, failedResponse).fire();
                            }
                        });

        try {
            requestWait.await(20, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

我在这里使用大超时来确保响应应该在超时结束之前返回,所以我可以断点并看到 WebCLient.send 方法被调用,然后它在 requestWait.wait(...) 处暂停但是在 CountDownLatch 超时之前永远不会调用回调。虽然我期待 WebClient 发送请求,并且当返回响应时,它会调用回调,作为回报,回调将倒计时并在 timwout 启动之前中断等待。

使用普通线程进行测试似乎可以正常工作,我创建了一些可运行的类,并带有一些睡眠时间......减去 CountDownTime 锁存器。像下面这样

public class SenderWorker implements Runnable {

    private CountDownLatch countDownLatch;

    public SenderWorker(CountDownLatch countDownLatch) {

        this.countDownLatch = countDownLatch;
    }

    @Override
    public void run() {
        try {
            Thread.sleep(5000L);
            countDownLatch.countDown();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

然后在调度程序中:

public class TestRequestDispatcher extends AbstractRequestDispatcher {

    @Override
    protected void dispatchRequest(ServerRequest request, ServerRequestEventFactory requestEventFactory) {

        CountDownLatch requestWait = new CountDownLatch(1);
        new Thread(new SenderWorker(requestWait))
                .start();

        try {
            requestWait.await(20, TimeUnit.SECONDS);
            System.out.println("i am here");
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

这行得通..它调用 run 方法..休眠,然后调用 requestWait.wait(..) 并在 5 秒后退出等待。

我尝试在executeBlocking 中执行调用WebClient 的代码,还尝试了runOnContext,甚至尝试在线程中运行它,就像我对SenderWorker 所做的那样,但结果仍然相同。 . WebClient 被阻塞直到超时。

知道我在这里做错了什么以及如何使它起作用吗?!

【问题讨论】:

    标签: java testing vert.x


    【解决方案1】:

    您可能需要考虑使用 vertx-unitvertx-junit5 使用 Vert.x 测试异步代码。

    除此之外,应该组合异步操作,而不是旋转线程并等待倒计时锁存器。 Vert.x 提供了几个选项来做到这一点:

    • 回调链接
    • 未来作曲
    • RxJava(1 和 2)
    • Kotlin 协程
    • 类星体。

    【讨论】:

    • 我已经在使用 vertx-unit,我想在 testContext.async 上进行中继,但是当我将 testcontext 的实例传递给框架调用的另一个方法时,它不会停止方法执行,因为它功能仅限于用@Before@After@Tests注释的测试方法
    猜你喜欢
    • 1970-01-01
    • 2021-08-17
    • 1970-01-01
    • 2020-02-14
    • 1970-01-01
    • 2015-12-28
    • 2017-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多