Correct way to fail a unit test from within a callback using Vertx Unit

1.5k Views Asked by At

Given the following unit test, which uses the Vertx Unit testing framework:

@RunWith(VertxUnitRunner.class)
public class VertxUnitTest {

    private Vertx vertx;

    @Rule
    public RunTestOnContext rule = new RunTestOnContext(new VertxOptions().setClustered(false)
            .setClusterManager(new HazelcastClusterManager()).setMaxEventLoopExecuteTime(2000000000000L)
            .setMaxWorkerExecuteTime(60000000000000L).setBlockedThreadCheckInterval(1000000)
            .setEventBusOptions(new EventBusOptions().setClustered(false).setIdleTimeout(0)));

    @Before
    public void setup() throws Exception {
        io.vertx.core.Vertx v = rule.vertx();
        vertx = Vertx.newInstance(v);
    }

    private class MyVerticle extends AbstractVerticle {}

    @Test
    public void runFlow_correctMessage_stepsCalledInCorrectOrder(TestContext context) {
        Async async = context.async();

        vertx.getDelegate().deployVerticle(new MyVerticle(), new DeploymentOptions().setWorker(true), c -> {
            c.cause();
            vertx.eventBus().<Object>send("", new JsonObject(), new DeliveryOptions(), rpl -> {
                async.complete();
                fail();

            });
        });
    }
}

the call to fail() is throwing an exception to the console, but it is not actually failing the test itself, which finishes successfully and is green.

The same is true when working with Mockito. I can successfully verify the behavior of the verticle and its dependencies using mocks, but even when the Mockito assertions fail, the test itself will still pass. Calling fail on the vertx TestContext object - context.fail() - will also not fail the test.

The core issue is this: any call to fail() after async.complete() will not fail the test, only the console will show the error. But without the call to async.complete(), the code in the verticle (called upon consuming from the event bus), will not have run before the test assertions are called.

Without the call to async.complete(), the test will it appears never complete.

What is the correct approach to this?

Thanks

1

There are 1 best solutions below

2
On BEST ANSWER

the correct approach is to call the TestContext.fail() method, like so:

@Test
public void runFlow_correctMessage_stepsCalledInCorrectOrder(TestContext context) {
    Async async = context.async();

    vertx.getDelegate().deployVerticle(new MyVerticle(), new DeploymentOptions().setWorker(true), c -> {
        if(c.succeeded()) {
            vertx.eventBus().<Object>send("", new JsonObject(), new DeliveryOptions(), rpl -> {
                if(rpl.succeeded()) {
                    // make assertions based on reply contents, and then...
                    async.complete();

                } else {
                    context.fail(rpl.cause());
                }
            });

        } else {
            context.fail(c.cause());
        }
    });
}