3

我有两个用 java vertx 编写的微服务。他们通过事件总线进行通信。第一个发送消息,第二个接收消息。

第一个想法:仅在单元测试中回复 Vertx 事件总线消息。

我想测试消息正在被正确处理,因此我在第二个微服务上编写单元测试来检查回复

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

现在我必须在我的消费者中发送回复,但我只想在测试中这样做,我不需要在生产中发送回复。我不想消耗 cpu 和网络在生产中发送回复。所以我正在寻找的是这样的:

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

第二个想法是在cdelmas 评论之后出现的,在我自己的回答中

4

2 回答 2

2

要在没有回复的情况下测试异步事件总线处理程序,您必须将业务逻辑提取到服务中并将测试用例分成两部分。首先用于消息传递,其次用于业务逻辑。

ConsumerVerticle 将如下所示:

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

methodMayFail()在异步测试中,使用将保持异步的重写方法来模拟您的服务

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

然后将模拟服务注入verticle

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

在另一个类MyServiceTest的某个地方测试methodMayFail().

于 2016-04-02T13:26:17.053 回答
0

仅为测试添加代码是一种非常糟糕的做法。

虽然你不回复,但可能你在消费者中做了一些可以检查的事情,比如更新一些状态。在我看来,这就是你应该在测试中断言的内容。

于 2016-03-25T12:34:16.247 回答