Я новичок в Vert.x 3, и я пытаюсь написать unit тест для простого обработчика событий. Прямо сейчас, все, что я пытаюсь сделать, это проверить, что тестируемая Verticle проверяет правильный компонент, который создается как макет с использованием Mockito.
Мой тестовый код выглядит примерно так:
@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!
info, поэтому я уверен, что выполнение теста достигает этой точки. Я просто не знаю, почему, в конце теста, в отчетах говорится, что взаимодействия с макетным объектом не было.
Проверка выполняется до вызова Mock. У вас должен быть асинхронный тест, который ждет до проверки. Как это:
@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());
}
Затем ваша вертикаль должна ответить на полученное сообщение, выполнив 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();
}
}
И тестовая вертикаль (синхронизация должна быть вызвана вашим макетом):
public class StackVerticle extends AbstractVerticle {
@Override
public void start() throws Exception {
vertx.eventBus().consumer("topic",received ->{
System.out.println("received");
StackTest.synchronisation.complete("done");
});
}
}