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

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

如果没有对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());
}
});
}

最新更新