我正在为我的 Vert.x 应用程序实现测试,但我在让 Vert.x 以优雅的方式等待 Verticle 部署时遇到问题。 这是我的@BeforeClass 方法:
@BeforeClass
public static void before(TestContext context)
{
vertx = Vertx.vertx();
DeploymentOptions options = new DeploymentOptions();
byte[] encoded;
JsonObject config;
try {
encoded = Files.readAllBytes(Paths.get("src/main/resources/config.json"));
config = new JsonObject(new String(encoded, Charset.defaultCharset()));
options.setConfig(config);
jdbc = JDBCClient.createShared(vertx, config , "PostgreSQL");
deployVerticle((result) -> loadTestData((result), jdbc), options);
while (true)
{
if (vertx.deploymentIDs().size() > 0)
break;
}
} catch
(IOException e)
{
e.printStackTrace();
}
}
此外,这里是 deployVerticle 和 loadTestData 方法的实现:
private static void deployVerticle(Handler<AsyncResult<Void>> next, DeploymentOptions options) {
vertx.deployVerticle(PostgreSQLClientVerticle.class.getName(), options, deployResult ->
{
if (deployResult.succeeded())
next.handle(Future.succeededFuture());
});
}
private static void loadTestData(AsyncResult<Void> previousOperation, JDBCClient jdbc)
{
if (previousOperation.succeeded())
{
jdbc.getConnection(connection -> {
if (connection.succeeded())
{
connection.result().query(deleteTestDataGeneration, queryResult ->
{
connection.result().close();
});
}
});
}
}
如您所见,现在我在 before
方法上有一个 while (true)
来保持流程并确保 Verticle 已实际部署。
否则,当测试开始运行时,Verticle 尚未完全部署,我得到一个 NullPointerException
试图访问资源。
我尝试过许多不同的方法,例如使用 CompositeFuture 或使用 Future.compose 方法来使“任务前”按顺序进行,并使程序等待完成。 我实现了按顺序执行这些任务,但未能在完成之前保持流程。
我认为,其中一个问题是 deployVerticle 方法在“部署过程”的每一步之后返回 AsyncResult
和 succeeded == true
的事实是完成,而不是在 Verticle 完全启动时。
这意味着该过程在一切实际启动之前就获得了成功的结果......但这只是一个大胆的猜测。
底线:我想找到一种方法来等待 Verticle 完全部署,然后再继续执行测试,而不必执行我目前的 while (true)
循环里面有。
最佳答案
您缺少的是 Async async = context.async();
。这样,单元测试就会保留在方法中,直到它未设置为完成为止。然后你就可以编排你的异步代码来:
- 首先部署verticle
- 然后执行loadtestGeneration
- 将异步设置为完成,以便其他单元测试方法已经可以访问您的 Verticle 而不会出现 nullpointerexception
我也做了一些清理,检查一下:
课前
@BeforeClass
public static void before2(TestContext context){
Async async = context.async();
vertx = Vertx.vertx();
DeploymentOptions options = new DeploymentOptions();
byte[] encoded;
JsonObject config;
try {
encoded = Files.readAllBytes(Paths.get("src/main/resources/config.json"));
config = new JsonObject(new String(encoded, Charset.defaultCharset()));
options.setConfig(config);
jdbc = JDBCClient.createShared(vertx, config , "PostgreSQL");
deployVerticle2(options)
.compose(c -> loadTestData2(jdbc))
.setHandler(h -> {
if(h.succeeded()){
async.complete();
}else{
context.fail(h.cause());
}
});
} catch (IOException e){
context.fail(e);
}
}
部署垂直
private static Future<Void> deployVerticle2(DeploymentOptions options) {
Future<Void> future = Future.future();
vertx.deployVerticle(PostgreSQLClientVerticle.class.getName(), options, deployResult -> {
if (deployResult.failed()){
future.fail(deployResult.cause());
}else {
future.complete();
}
});
return future;
}
加载测试数据
private static Future<Void> loadTestData2(JDBCClient jdbc){
Future<Void> future = Future.future();
jdbc.getConnection(connection -> {
if (connection.succeeded()) {
connection.result().query(deleteTestDataGeneration, queryResult -> {
if(queryResult.failed()){
connection.result().close();
future.fail(queryResult.cause());
}else{
connection.result().close();
future.complete();
}
});
} else {
future.fail(connection.cause());
}
});
return future;
}
关于java - 如何让测试等待 Vert.x Verticle 部署完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54234288/