2016-09-21 98 views
1

我是新來的Vert.x 3,我正在嘗試爲一個簡單的事件處理函數編寫一個單元測試。現在,我所要做的就是檢查被測試的Verticle委託給正確的組件,該組件使用Mockito創建爲模擬。如何在Vert.x中測試事件處理程序(來自事件總線)?

我測試的代碼看起來是這樣的:

@Rule 
public final RunTestOnContext vertxRule = new RunTestOnContext(); 

@Before 
public void setUp(TestContext context) { 
    vertx = vertxRule.vertx(); 
    //verticle is set up with mock delegate before deployment 
    vertx.deployVerticle(verticle); 
} 

@After 
public void tearDown(TestContext context) { 
    vertx.close(context.asyncAssertSuccess()); 
} 

@Test 
public void testDelegate(TestContext context) { 
    EventBus eventBus = vertx.eventBus(); 
    Event event = new Event("id", "description") 
    eventBus.publish("event.channel", Json.encode(event)); 

    //Mockito.verify 
    verify(delegate).invokeMethod(anyString(), anyString()); 
} 

的Veticle包含類似於下面的代碼:

private Delegate delegate; 

@Override 
public void start(Future<Void> future) throws Exception { 
    vertx.eventBus().consumer("event.channel", message -> { 
     logger.info("received!"); 
     Event event = Json.decodeValue(message.body().toString(), Event.class); 
     delegate.invokeMethod(event.getId(), event.getDescription()); 
    }); 
} 

不過,我每次運行測試時,我總是得到一個錯誤說法模擬沒有被調用。我確信模擬對象被正確注入,因爲如果我在事件總線結構之外調用它,測試就會通過。此外,代碼記錄了received!信息,所以我確信測試執行達到了這一點。我只是不確定爲什麼,在測試結束時,報告表示與模擬對象沒有互動。

回答

2

驗證在模擬被調用之前執行。您應該在驗證之前等待測試中的異步。就像這樣:

@Test 
public void testDelegate(TestContext context) { 
    EventBus eventBus = vertx.eventBus(); 
    Event event = new Event("id", "description") 
    Async async = context.async(); 
    eventBus.publish("event.channel", Json.encode(event) ,done ->async.complete()); 


    async.await() 

    //Mockito.verify 
    verify(delegate).invokeMethod(anyString(), anyString()); 
} 

那麼你verticle必須通過調用模擬後做message.reply(...)回覆收到的消息。你對任何答覆意見後

編輯

我嘗試使用同步一個全局變量(醜陋的),下面的代碼(注意,這是一個io.vertx.core.Future):

@RunWith(VertxUnitRunner.class) 
public class StackTest { 

    private Vertx vertx; 
    public static Future<String> synchronisation = Future.future(); 

    @Before 
    public void setUp(TestContext context) { 
     vertx = Vertx.vertx(); 
     vertx.deployVerticle(new StackVerticle()); 
    } 

    @Test 
    public void testPublish(TestContext context){ 
     vertx.eventBus().publish("topic","message"); 
     Async async = context.async(); 
     synchronisation.setHandler(event -> async.complete()); 
     async.await(); 
    } 
} 

而且測試verticle(該synchronization.complete必須由模擬觸發):

public class StackVerticle extends AbstractVerticle { 
    @Override 
    public void start() throws Exception { 
     vertx.eventBus().consumer("topic",received ->{ 
      System.out.println("received"); 
      StackTest.synchronisation.complete("done"); 
     }); 
    } 
} 
+0

我不需要我的Verticle到,雖然回答。 –

+1

這是一個問題。由於eventbus.publish()異步通知使用者,因此測試中的下一個java語句(即Mockito.verify)將繼續執行。調用委託後,您必須找到一種方法來執行此驗證。 – Alibi

+0

用一些新代碼編輯我的答案 – Alibi

相關問題