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

标签 java testing junit service vert.x

我正在为我的 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 方法在“部署过程”的每一步之后返回 AsyncResultsucceeded == 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/

相关文章:

java - 如何集成测试加密的 URL

java - 使用从 ajax 加载的 div 时的 Struts2 验证

java - 可包裹 : Creating an instance of creator and implementing methods inline - CREATOR is an interface?

java - 为使用 Struts 构建的网站编写中间层测试

scala - Play2 和 Scala,我应该如何配置集成测试以使用正确的数据库运行

java - 支持 JUnit 测试注释的代码覆盖工具,用于指定 UnitTest 覆盖哪种方法

java - 如何将多部分表单数据从jsp发送到Web服务?

java - 如何从 junit 中的 java 扩展文件中读取和测试类?我怎样才能访问该类进行测试?

unit-testing - 通过模拟 getter 测试类

java - Spring的JUnit测试加载ApplicationContext失败