2015-09-07 51 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();  
    } 

希望它可以幫助一些機構在未來。