使用 Vertx Unit 从回调中使单元测试失败的正确方法

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

给定以下单元测试,它使用 Vertx Unit 测试框架:

@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();

            });
        });
    }
}

fail() 的调用向控制台抛出异常,但它实际上并没有使测试本身失败,它成功完成并显示为绿色。

使用 Mockito 时也是如此。我可以使用模拟成功验证 Verticle 及其依赖项的行为,但即使 Mockito 断言失败,测试本身仍会通过。在 vertx TestContext 对象上调用失败 - context.fail() - 也不会使测试失败。

核心问题是:在async.complete()之后对fail()的任何调用都不会失败,只有控制台会显示错误。但是如果不调用 async.complete(),Verticle 中的代码(从事件总线调用)在调用测试断言之前将不会有 运行。

如果不调用 async.complete(),测试似乎永远不会完成。

正确的做法是什么?

谢谢

正确的做法是调用TestContext.fail()方法,像这样:

@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());
        }
    });
}