0

io.vertx.reactivex.core.eventbus.EventBus.rxSend()方法具有以下签名:

public <T> Single<Message<T>> rxSend(String address,
                                     Object message,
                                     DeliveryOptions options)

模拟它以使其返回Single包含真实对象的正确方法是什么?问题是Message该类没有构造函数,除了一个接受另一个Message对象的构造函数。所以下面会编译:

Mockito.when(eventBus.rxSend(Mockito.isA(String.class), 
   Mockito.isA(JsonObject.class), 
   Mockito.isA(DeliveryOptions.class))).thenReturn(Single.just(new Message<Object>(null)));

但当然Single.just(new Message<Object>(null))不包含一个真实的对象,然后可以将其传递给测试verticle中的下一个处理程序。

谢谢

4

1 回答 1

2

就像我在评论中提到的那样,我对您的直接问题没有答案,但我想推荐一种不同的方法来获得您正在寻找的结果。

出于各种原因,通常不鼓励模拟您不拥有的类型。最能引起我共鸣的两个(因为我已经成为受害者)是:

  • 如果模拟依赖项的实际实现发生变化,模拟的行为将不会自动显示任何前向更改。
  • 测试引入的模拟越多,测试承载的认知负荷就越大。有些测试需要大量模拟才能工作。

有很多关于该主题的文章,其中包含更详细的观点和意见。如果您有兴趣,请参阅Mockito wiki或只是 Google 周围。

鉴于所有这些,而不是嘲笑EventBus,为什么不使用实际实例并接收Messages由框架组成的真实回复呢?当然,严格来说,这更像是集成测试而不是单元测试,但更接近您想要的测试类型。

这是我在现有项目中编写的测试的示例片段,并添加了一些注释。(代码指的是一些带有 -"Ext" 后缀的非标准类型,但它们并不突出这种方法)。

private EventBus eventBus;

@Before
public setUp(@NotNull TestContext context) {
    eventBus = Vertx.vertx().eventBus()
}

@Test
public void ping_pong_reply_test(@NotNull TestContext context) {
    final Async async = context.async();

    // the following is a MessageConsumer registered 
    // with the EventBus for this specific test. 
    // the reference is retained so that it can be 
    // "unregistered()" upon completion of this test
    // so as not to affect other tests. 

    final MessageConsumer<JsonObject> consumer = eventBus.consumer(Ping.class.getName(), message -> {
        // here is where you would otherwise place
        // your mock Message generation.

        MessageExt.replyAsJsonObject(message, new Pong());
    });

    final Ping message = new Ping();
    final DeliveryOptions options = null;

    // the following uses an un-mocked EventBus to 
    // send an event and receive a real Message reply.
    // created by the consumer above.

    EventBusExt.rxSendJsonObject(eventBus, message, options).subscribe(
            result -> 
                // result.body() is JSON that conforms to 
                // the Pong type

                consumer.unregister();

                async.complete();
            },
            error -> {
                context.fail(error);
            }
    );
}

我希望这至少能激发一些围绕您的问题的新思维。

于 2018-09-04T04:05:05.367 回答