Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test async vertx eventbus handlers without sending reply

I have two microservices written with java vertx. They communicate via eventbus. First one sends a message and second receives the message.

First idea: Only reply to Vertx eventbus messages in unit test.

I want to test that message is being processed without errors and therefore I write unit test on second microservice that checks the reply

eventbus.send("address", message, reply -> {
    if (reply.succeeded()) {
        context.async().complete();
    } else {
        context.fail();
    }});

Now I have to send reply in my consumer, but I want to do it only in test, I do not need to send replies in production. I do not want to consume cpu and network to send replies in production. So what I am looking for is something like this:

vertx.eventBus().consumer("address", handler -> {
    Boolean success = methodMayFail();
    if ( MY_CONTEXT_IS_TEST || HANDLER_IS_LOCAL_AS_I_ONLY_SENT_LOCAL_MESSAGES_FROM_TEST) {
        success ? handler.reply("ok") : handler.fail();
    }
});

Second idea came after cdelmas comment and is in my own answer

like image 804
Anton Ivinskyi Avatar asked Jan 17 '26 22:01

Anton Ivinskyi


1 Answers

To test async eventbus handler without reply you have to extract your business logic into service and split your test case into two. First for message passing, second for business logic.

ConsumerVerticle will look like this:

class ConsumerVerticle extends AbstractVerticle {
    // this service is injected somehow, for example as constructor parameter
    private MyService service;
    ...
    public void start() {
        vertx.eventBus().consumer("address", handler -> {
            service.methodMayFail();
        });
    }
}

In async test implement mock of your service with overridden method methodMayFail() that will hold the async

class MockService extends MyService() {
    private Async async;
    public MockService(Async async) {
        this.async = async;
    }
    @Override public void methodMayFail() {
        async.complete()
    }
}

And then inject the mock service into verticle

MockService service = new MockService(context.async()); 
ConsumerVerticle consumerVerticle = new ConsumerVerticle(service);
...
eventbus.send("address", message)

Somewhere in another class MyServiceTest test the implementation of methodMayFail().

like image 114
Anton Ivinskyi Avatar answered Jan 19 '26 11:01

Anton Ivinskyi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!