如何让测试等待Vert.x Verticle部署完成



我正在为我的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),用于保持流程并确保vertical实际部署。否则,当测试开始运行时,vertical还没有完全部署,我得到了一个NullPointerException,试图访问资源。

我尝试了许多不同的方法,比如使用CompositeFuture或使用Future.compose方法来使"任务前"按顺序排列,并使程序保持完成状态。我成功地使这些任务按顺序进行,但未能坚持到完成为止。

我认为,其中一个问题是,deployVerticle方法在"部署过程"的每一步完成后,而不是在Verticle完全启动时,返回带有succeeded == trueAsyncResult

这意味着在一切真正结束之前,这个过程会取得成功。。。但这只是一个疯狂的猜测。

一句话:我想找到一种方法,在继续执行测试之前,等待Verticle完全部署,而不必执行我目前拥有的while (true)循环。

您缺少的是Async async = context.async();。这样,单元测试就一直保留在方法中,直到它没有设置为完成为止。然后,您可以将异步代码编排为:

  • 首先部署垂直
  • 然后执行loadtestGeneration
  • 将async设置为complete,这样其他unittest方法就可以在没有nullpointerexception的情况下访问您的vertical

我也做了一些清理,看看:

BeforeClass

@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);
}
}

DeployVerticle

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;
}

LoadTestData

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;
}

最新更新