单元测试 Vertx - java.util.concurrent.TimeoutException
Unit testing Vertx - java.util.concurrent.TimeoutException
我正在尝试使用 VertxUnitRunner
和 RX 版本的 vertx 对来自 vertx WebClient
的 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[=12=](TestContextImpl.java:112)
at java.lang.Thread.run(Thread.java:745)
因为你对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
您可以尝试添加超时规则
@Rule
public Timeout timeoutRule = Timeout.seconds(3600);
我正在尝试使用 VertxUnitRunner
和 RX 版本的 vertx 对来自 vertx WebClient
的 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[=12=](TestContextImpl.java:112)
at java.lang.Thread.run(Thread.java:745)
因为你对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
您可以尝试添加超时规则
@Rule
public Timeout timeoutRule = Timeout.seconds(3600);