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

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


person Psycho Punch    schedule 21.09.2016    source источник


Ответы (1)


Проверка выполняется до вызова 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();
    }
}  

И тестовая вертикаль (синхронизация.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");
        });
    }
}
person Alibi    schedule 21.09.2016
comment
Однако мне не нужна моя Вертикаль для ответа. - person Psycho Punch; 21.09.2016
comment
это проблема. Поскольку eventbus.publish () уведомляет потребителя асинхронно, выполнение продолжается на вашем следующем java-выражении в тесте, которым является Mockito.verify. Вы должны найти способ выполнить эту проверку после вызова вашего делегата. - person Alibi; 21.09.2016