1

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

@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时也是如此。我可以使用 mock 成功验证 Verticle 的行为及其依赖关系,但即使 Mockito 断言失败,测试本身仍然会通过。在 vertx TestContext 对象上调用 fail - context.fail()- 也不会使测试失败。

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

如果没有调用async.complete(),测试将永远不会完成。

对此的正确方法是什么?

谢谢

4

1 回答 1

3

正确的方法是调用该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());
        }
    });
}
于 2018-11-20T01:53:46.957 回答