Как заставить тесты ждать завершения развертывания Vert.x Verticle - PullRequest
0 голосов
/ 17 января 2019

Я выполняю тесты для моего приложения 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, чтобы удержать процесс и убедиться, что вертикаль действительно развернута. В противном случае, когда тесты начнут выполняться, вертикаль еще не развернута полностью, и я получаю NullPointerException, пытающуюся добраться до ресурсов.

Я пробовал много разных подходов, таких как использование CompositeFuture или метод Future.compose, чтобы сделать последовательность «перед заданиями» последовательной и заставить программу удерживаться до завершения. Я добился последовательного выполнения этих задач, но не смог удержать процесс до их завершения.

Одной из проблем, я думаю, является тот факт, что метод deployVerticle возвращает AsyncResult с succeeded == true после каждого шага «процедуры развертывания», а не когда Verticle полностью запущен.

Это означает, что процесс получает успешный результат до того, как все будет на самом деле ... но это только дикое предположение.

Итог: я хотел бы найти способ дождаться полного развертывания Verticle, прежде чем приступить к выполнению тестов, без необходимости выполнять цикл while (true), который у меня есть в настоящее время.

1 Ответ

0 голосов
/ 17 января 2019

То, что вам не хватает, это Async async = context.async();. При этом юнит-тест остается в методе до тех пор, пока он не будет установлен для завершения. Затем вы можете организовать свой асинхронный код:

  • сначала разверните вертикаль
  • затем выполните loadtestGeneration
  • установить асинхронное выполнение так, чтобы другие методы юнит-теста уже могли получить доступ к вашей вертикалке без nullpointerexception

Я также сделал некоторую очистку, проверьте это:

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