java - 如何让测试等待 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();
});
}
});
}
}
如您所见,现在我有一个while (true)
方法before
来保存进程并确保实际部署了verticle。否则,当测试开始运行时,verticle 尚未完全部署,我NullPointerException
尝试获取资源。
我尝试了许多不同的方法,例如使用 CompositeFuture 或使用 Future.compose 方法来使“之前的任务”连续并让程序等待完成。我在使这些任务按顺序完成方面取得了成就,但未能在完成之前保持该过程。
我认为,其中一个问题是,deployVerticle 方法在“部署过程”的每一步完成后返回AsyncResult
with succeeded == true
,而不是在 Verticle 完全启动时返回。
这意味着该过程在一切真正启动之前就获得了成功的结果……但这只是一个疯狂的猜测。
底线:我想找到一种方法来等待 Verticle 完全部署,然后再继续执行测试,而不必执行while (true)
我目前在那里的循环。
解决方案
你缺少的是Async async = context.async();
. 这样,unittest 将保留在方法中,直到它未设置为完成。然后,您可以将异步代码编排为:
- 首先部署verticle
- 然后执行 loadtestGeneration
- 将异步设置为完成,以便其他单元测试方法已经可以在没有 nullpointerexception 的情况下访问您的 Verticle
我也做了一些清理,检查一下:
课前
@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);
}
}
部署Verticle
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;
}
推荐阅读
- javascript - 我正在尝试使用三个 js 在 glsl 着色器中制作棋盘纹理,但它变得混叠或像素化,如何使其平滑?
- node.js - 项目结构的 Heroku 部署 postbuild
- object-detection - yolov3无法检测灰度图像中的物体
- kubernetes - 为什么即使时间阈值为 1 分钟,gcp 警报的警报仍不会降至 0?
- c# - 使用 Nest 进行 ElasticSearch 查询 - 将字段匹配到几个选项之一
- php - 图片上传的圆形边框并合并到php中的另一个模板
- bash - Bash (WSL):无法限制使用 ulimit -f 写入的文件的大小
- javascript - 按下提交按钮时隐藏 div
- django - 在 Django 表单上使用小部件
- java - 如何为 X.0.4472.114 之类的东西创建一个正则表达式,其中 X 是一个数字?