springwebflux&mockito:如何验证流的使用和参与的处理程序的调用

klr1opcd  于 2021-06-29  发布在  Java
关注(0)|答案(1)|浏览(307)

我在用Spring做实验。我对java中的React流比较陌生。我正忙于研究如何在React流中测试和验证对象协作。我正在使用spring测试和reactor测试库进行tdd测试。
这是有缺陷的测试

@Test
void givenWeatherService_whenGetWeather_thenPublishWeatherAsync() throws Exception {

    Mono<Sample> mono = service.updateWeatherFeed();

    RecordedRequest request = server.takeRequest();
    assertThat(request.getMethod()).isEqualTo("GET");
    assertThat(request.getPath()).isEqualTo("/api/weather");

    StepVerifier.create(mono)
        .assertNext(sample -> {
            verify(publisher, times(1)).publish(sample);
            verify(sensorRepository, times(1)).insertSample(sample);
        }).verifyComplete();
}

下面是服务方法的实现

public Mono<Sample> updateWeatherFeed() {

    // Uses WebClient to return the stream
    Mono<Sample> mono = getWeather();

    mono.doOnNext(sample -> {
        sensorRepository.insertSample(sample);
        samplePublisher.publish(sample);
    }).subscribe();

    return mono;
}

stepverifier挂起以下日志:

10:21:01.827 [reactor-http-nio-2] DEBUG reactor.netty.resources.DefaultPooledConnectionProvider - [id: 0x81e9584a, L:/127.0.0.1:62510 - R:localhost/127.0.0.1:62479] Channel cleaned, now 1 active connections and 1 inactive connections

正确的方法是什么来验证流是否已被使用以及参与的处理程序是否按顺序被调用?

dwbf0jvd

dwbf0jvd1#

你的问题可能是:

public Mono<Sample> updateWeatherFeed() {

    // Uses WebClient to return the stream
    Mono<Sample> mono = getWeather();

    mono.doOnNext(sample -> {
        sensorRepository.insertSample(sample);
        samplePublisher.publish(sample);
    }).subscribe(); // <--- right here

    return mono;
}

您将看到您正在订阅并因此使用流。如果您查看mono#subscribe的api,您可以看到它返回一个一次性的。这意味着它已经被消耗,并准备好被处置。
React流包括 producer 和一个 consumer . 这个
consumer subscribesproducer 然后开始 publishing . 发起呼叫的人是 consumer 因此应该是 subscribe .
在您的例子中,测试是发起调用的测试,因此测试是 consumer 应该是那个 subscribing .
如果我们看看stepverifier#create,我们会发现它需要 Publisher 而出版商是一个非消费者 Mono 或者 Flux ,不是 Disposable .
那么我们该如何解决这个问题,你需要移除 subscribe() ```
public Mono updateWeatherFeed() {
return getWeather().flatMap(sample -> {
sensorRepository.insertSample(sample);
samplePublisher.publish(sample);
return sample;
});
}

那你就不需要 `StepVerifier` 既然你还了一个 `Mono` 这只是一个项目。如果你在哪里测试 `Flux` 你可以用 `StepVerifier` “跨过”你的 `Flux` .

// Set up mocks and such

@Test
void doTest() throws Exception {

final Service service = new Service(publisherMock, sensorRepositoryMock);
final Sample sample = service.updateWeatherFeed().block();

// Assert Sample
assertEquals(sample, ...);

// Verify mocks
verify(publisherMock, times(1)).publish(sample);
verify(sensorRepositoryMock, times(1)).insertSample(sample);

}

我写这封信已经有一段时间了,但我是徒手写的,所以我希望你至少能理解其中的要点。

相关问题