How can I make tests wait for Vert.x Verticle deployment to be completed

问题: I am implementing tests for my Vert.x application, but I am having issues in making Vert.x wait for the deploy of the Verticle in a graceful way. This is my @BeforeClass Me...

问题:

I am implementing tests for my Vert.x application, but I am having issues in making Vert.x wait for the deploy of the Verticle in a graceful way. This is my @BeforeClass Method:

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

Also, here is the implementation for the deployVerticle and loadTestData methods:

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

As you can see, right now I have a while (true) on the beforemethod to hold the process and make sure the verticle is actually deployed. Otherwise, when the tests start running, the verticle is not yet fully deployed and I get a NullPointerException trying to reach the resources.

I've tried many different approaches like using CompositeFuture or using Future.compose method to make the "before tasks" sequential and make the program hold for completion. I achieved in making those tasks sequential but failed on holding the process until they are completed.

One of the issues is, I think, the fact that the deployVerticle method returns the AsyncResult with succeeded == true after every step of the "deploy procedure" is done, instead of when the Verticle is totally up.

Meaning that the process gets a successful result before everything is actually up...but this is just a wild guess.

Bottom-line: I would like to find a way to wait for the Verticle to be totally deployed before proceeding to perform the tests, without having to do the while (true)loop that I currently have in there.


回答1:

What you are missing is the Async async = context.async();. With that the unittest stays in the method until it is not set to complete. Then you are able to orchestrate your asychronous code to:

  • first deploy the verticle
  • then execute the loadtestGeneration
  • set the async to complete so that, the other unittest methods already can access to your verticle without nullpointerexception

I also made some cleanup, check it out:

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;
  }
  • 发表于 2019-01-18 22:23
  • 阅读 ( 248 )
  • 分类:网络文章

条评论

请先 登录 后评论
不写代码的码农
小编

篇文章

作家榜 »

  1. 小编 文章
返回顶部
部分文章转自于网络,若有侵权请联系我们删除