介绍
Vertx-junit5该模块为使用 JUnit 5 编写 Vert.x 测试提供集成和支持
1. maven项目依赖
<dependencies>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web</artifactId>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-config-yaml</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.lance.common</groupId>
<artifactId>vertx-common-core</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- Test -->
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-junit5</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
2.YAML文件配置
server:
port: 18002
3.启动加载配置文件, 并放入到config中去
public class UnitApplication {
public static void main(String[] args) {
Vertx vertx = Vertx.vertx();
ConfigRetriever retriever = readYaml(vertx);
retriever.getConfig(json -> {
DeploymentOptions options = new DeploymentOptions().setConfig(json.result());
vertx.deployVerticle(MainApp.class.getName(), options);
});
}
private static ConfigRetriever readYaml(Vertx vertx) {
ConfigStoreOptions store = new ConfigStoreOptions()
.setType("file")
.setFormat("yaml")
.setOptional(true)
.setConfig(new JsonObject().put("path", "application.yaml"));
return ConfigRetriever.create(vertx, new ConfigRetrieverOptions().addStore(store));
}
}
4.Vertx http client单元测试
Slf4j
@ExtendWith(VertxExtension.class)
class WebRequestTests {
private final Vertx vertx = Vertx.vertx();
/**
* test vertx server
*/
@Test
@Disabled
void suite() {
vertx.createHttpServer()
.requestHandler(req -> req.response().end("Ok"))
.listen(16969, ar -> {
log.info("===> vertx start: {}", ar.succeeded());
});
}
/**
* 1.允许等待其他线程中的操作以通知完成, 类似java中promise对象
* 2.支持接收断言失败以将测试标记为失败
*/
@Test
@Disabled
void asyncContext() throws Throwable {
VertxTestContext testContext = new VertxTestContext();
vertx.createHttpServer()
.requestHandler(req -> req.response().end())
.listen(16969)
.onComplete(testContext.succeedingThenComplete());
//.onComplete(testContext.failingThenComplete());
Assertions.assertTrue(testContext.awaitCompletion(5, TimeUnit.SECONDS));
if (testContext.failed()) {
throw testContext.causeOfFailure();
}
}
/**
* Test http client
*/
@Test
@Disabled
void httpClient() throws Exception {
HttpClient client = vertx.createHttpClient();
VertxTestContext testContext = new VertxTestContext();
client.request(HttpMethod.GET, 18002, "127.0.0.1", "/user/info/2")
.compose(req -> req.send().compose(HttpClientResponse::body))
.onComplete(testContext.succeeding(buffer -> testContext.verify(() -> {
JsonObject jsonObject = buffer.toJsonObject();
log.info("===>Response body: {}", jsonObject);
Assertions.assertEquals(jsonObject.getString("code"), HttpResponseStatus.OK.reasonPhrase());
testContext.completeNow();
}))).onFailure(event -> log.error("===>fail: ", event.getCause()));
boolean awaitResult = testContext.awaitCompletion(30, TimeUnit.SECONDS);
log.info("===>Await: {}", awaitResult);
}
/**
* 只需调用即可将许多测试标记为通过completeNow在执行的某个时间点。话虽如此,在许多情况下,测试的成功取决于要验证的不同异步部分。
*/
@Test
@Disabled
void checkpoint() {
int port = 9001;
VertxTestContext testContext = new VertxTestContext();
Checkpoint serverStarted = testContext.checkpoint();
Checkpoint requestsServed = testContext.checkpoint(10);
Checkpoint responsesReceived = testContext.checkpoint(10);
vertx.createHttpServer()
.requestHandler(req -> {
req.response().end("success");
requestsServed.flag();
})
.listen(port)
.onComplete(testContext.succeeding(httpServer -> {
serverStarted.flag();
HttpClient client = vertx.createHttpClient();
for (int i = 0; i < 10; i++) {
client.request(HttpMethod.GET, port, "localhost", "/")
.compose(req -> req.send().compose(HttpClientResponse::body))
.onComplete(testContext.succeeding(buffer -> testContext.verify(() -> {
Assertions.assertEquals("success", buffer.toString());
responsesReceived.flag();
}))
);
}
})
);
}
}
5.Vertx test context单元测试
@Slf4j
@ExtendWith(VertxExtension.class)
class VertxExtensionTests {
private final int port = 9000;
@BeforeEach
void init(Vertx vertx, VertxTestContext testContext) {
vertx.deployVerticle(new HttpServerVertical(), testContext.succeedingThenComplete());
}
@AfterEach
public void after(Vertx vertx) {
log.info("===>Vertx close.");
vertx.close();
}
/**
* 连续测试3次
* repetition 1 of 3
* repetition 2 of 3
* repetition 3 of 3
*/
@Disabled
@RepeatedTest(3)
void request3Times(Vertx vertx, VertxTestContext testContext) {
HttpClient client = vertx.createHttpClient();
client.request(HttpMethod.GET, port, "localhost", "/")
.compose(req -> req.send().compose(HttpClientResponse::body))
.onComplete(testContext.succeeding(buffer -> testContext.verify(() -> {
log.info("===>Response result: {}", buffer.toString());
testContext.completeNow();
})));
}
@Test
@Timeout(value = 100, unit = TimeUnit.MILLISECONDS)
void timeout(Vertx vertx, VertxTestContext testContext) {
HttpClient client = vertx.createHttpClient();
client.request(HttpMethod.GET, port, "localhost", "/")
.compose(req -> req.send().compose(HttpClientResponse::body))
.onComplete(testContext.succeeding(buffer -> testContext.verify(() -> {
Thread.sleep(5000L);
log.info("===>Response timeout result: {}", buffer.toString());
testContext.completeNow();
})));
}
/**
* 单服务测试
*/
@Test
@Disabled
void httpServerResponse(Vertx vertx, VertxTestContext testContext) {
vertx.deployVerticle(new HttpServerVertical(), testContext.succeeding(id -> {
HttpClient client = vertx.createHttpClient();
client.request(HttpMethod.GET, port, "localhost", "/")
.compose(req -> req.send().compose(HttpClientResponse::body))
.onComplete(testContext.succeeding(buffer -> testContext.verify(() -> {
log.info("===>Response result: {}", buffer.toString());
Assertions.assertEquals(buffer.toString(), "success");
testContext.completeNow();
})));
}));
}
class HttpServerVertical extends AbstractVerticle {
@Override
public void start() throws Exception {
vertx.createHttpServer()
.requestHandler(req -> {
req.response().end("success");
})
.listen(port).onComplete(event -> {
if (event.succeeded()) {
log.info("===>Start [{}] success!", port);
return;
}
log.error("===>Start fail: ", event.cause());
});
}
}
}