【发布时间】: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 被阻塞直到超时。
知道我在这里做错了什么以及如何使它起作用吗?!
【问题讨论】: