2016-09-21 53 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