Как я могу тестировать обработчики событий (из шины событий) в Vert.x?

2

Я новичок в 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, поэтому я уверен, что выполнение теста достигает этой точки. Я просто не знаю, почему, в конце теста, в отчетах говорится, что взаимодействия с макетным объектом не было.

Теги:
vert.x

1 ответ

3

Проверка выполняется до вызова 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");
        });
    }
}
  • 0
    Мне не нужна моя статья, чтобы ответить.
  • 1
    это проблема. Поскольку eventbus.publish () уведомляет потребителя асинхронно, выполнение продолжается для вашего следующего java-оператора в тесте, который является Mockito.verify. Вы должны найти способ выполнить эту проверку после вызова вашего делегата.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню