2015-09-07 2 views
2

У меня есть тест junit, где я хотел бы создать кластерную среду vert.x. Он отлично работает, если я запускаю код в методе setUp из метода public static void main(), но не если он запущен из метода setUp.
Метод public void handle(AsyncResult<Vertx> res) никогда не вызывается! Почему?Не удается настроить кластеризованную среду Vert.x из моего теста JUnit

@RunWith(VertxUnitRunner.class) 
public class TestMyStuff { 
    private Vertx vertx; 

    @Before 
    public void setUp(TestContext context) throws IOException { 

     ClusterManager mgr = new HazelcastClusterManager(); 
     VertxOptions options = new VertxOptions().setClusterManager(mgr); 
     Vertx.clusteredVertx(options, new Handler<AsyncResult<Vertx>>() { 
      @Override 
      public void handle(AsyncResult<Vertx> res) { 
       if(res.succeeded()) { 
        vertx = res.result(); 

        DeploymentOptions options = new DeploymentOptions() 
          .setConfig(new JsonObject().put("http.port", 8080) 
          ); 
        vertx.deployVerticle(MyWebService.class.getName(), options, context.asyncAssertSuccess()); 
        System.out.println("SUCCESS"); 
       } else { 
        System.out.println("FAILED"); 
       } 
      } 
     }); 
    } 

    @Test 
    public void printSomething(TestContext context) { 
     System.out.println("Print from method printSomething()"); 
    } 

"Print from method printSomething()" является неоспоримым написана, но не "SUCCESS" или "FAILED" от метода ручки().

Почему он не работает в методе setUp, но из main()?

ответ

2

тест не настроен должным образом из-за асинхронной поведения VertX:

  • Код внутри @Before начинает VertX в асинхронном режиме с Vertx.clusteredVertx(), но это просто оленья кожа» t успевать даже начать VertX
  • Метод printSomething() начинается сразу после вызова clusteredVertx() (без запуска VertX), сам тест заканчивается, поэтому JUnit останавливает весь тестовый процесс, убивая нечетное начальное VertX

У меня есть e Некоторое время назад эта проблема возникла, и что вы должны делать в этой ситуации?

Вы должны правильно настроить VertX и подождать в методе тестирования, чтобы завершить настройку. Я мог бы выполнить это с помощью механизма ожидания, используя Awaitility (https://github.com/jayway/awaitility).

Основные пункты

  • установить переменную ждать настройки VertX
  • в обработчик вызова clusteredVertx, установите переменную истинного
  • и, наконец, ждать этой переменной должен быть установлен в методе испытаний

Я

@RunWith(VertxUnitRunner.class) 
public class TestMyStuff { 
    private Vertx vertx; 

    final AtomicBoolean loaded = new AtomicBoolean(false); 

    @Before 
    public void setUp(TestContext context) throws IOException { 
    ClusterManager mgr = new HazelcastClusterManager(); 
    VertxOptions options = new VertxOptions().setClusterManager(mgr); 
    Vertx.clusteredVertx(options, new Handler<AsyncResult<Vertx>>() { 
     @Override 
     public void handle(AsyncResult<Vertx> res) { 
      if (res.succeeded()) { 
       vertx = res.result(); 

       DeploymentOptions options = new DeploymentOptions() 
         .setConfig(new JsonObject().put("http.port", 8080) 
         ); 
       //vertx.deployVerticle(MyWebService.class.getName(), options, context.asyncAssertSuccess()); 
       System.out.println("SUCCESS"); 
       loaded.set(true); 
      } else { 
       System.out.println("FAILED"); 
      } 
     } 
     }); 
    } 

    @Test 
    public void printSomething(TestContext context) { 


    Awaitility.waitAtMost(Duration.ONE_MINUTE).await().untilTrue(loaded); 
    System.out.println("Print from method printSomething()"); 
    } 
} 

Надеюсь, это поможет понять главный момент, так что вы можете найти любой другой способ обхода!

+0

Спасибо! Я просто решил это, используя простой wait/notify. Любые плюсы и минусы с этим? – Rox

+0

Поскольку сам vertx основан на асинхронной работе, и JUnit требует синхронного способа определения результатов, если вы хотите получить полный интеграционный тест, я не думаю, что есть более простой/элегантный способ. Тем не менее, вы можете рассмотреть возможность проверки только бизнес-логики, используемой вашими вершинами, а не всего стека vertx (так как вы можете ожидать, что vertx будет работать правильно). – gabowsky

1

VertX имеет свою функцию для обработки многопоточности и асинхронного запроса.

Просто используйте класс Async в функции Test:

@Test 
    public void printSomething(TestContext context) { 
     Async async = context.async(); 
     System.out.println("Print from method printSomething()"); 
     async.complete();  
    } 

Надеется, что это помогает некоторое телу в будущем.

Смежные вопросы