2015-09-07 32 views
2

我有一个junit测试,我想设置一个集群vert.x环境。如果我运行public static void main()方法中的setUp方法中的代码,但运行方法不是setUp,则运行正常。
从不调用public void handle(AsyncResult<Vertx> res)方法! 为什么?无法从我的JUnit测试中设置集群Vert.x环境

@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()” 被写入beeing但不是 “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呼叫处理程序的设置,将变量设置为true
  • 终于,等待这个变量在测试方法

@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

谢谢!我刚刚通过使用简单的等待/通知来解决它。任何优点和缺点呢? – Rox

+0

由于vertx本身是基于异步操作的,而JUnit需要同步的方式来确定结果,所以如果你想要一个完整的集成测试,我不认为有更简单/更优雅的方法。但是,您可以考虑仅测试Verticle使用的业务逻辑,而不测试整个vertx堆栈(因为您可以期望vertx正常工作..) – gabowsky

1

VertX确实有自己的函数来处理多线程和异步请求。

只需使用异步类在您的测试功能:

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

希望它可以帮助一些机构在未来。