Можно ли использовать виртуальное время StepVerifier в Reactor с SchedulerClock для управления временем в тестах?

#java #unit-testing #time #project-reactor

#java #модульное тестирование #время #проект-реактор

Вопрос:

Я пытаюсь использовать SchedulerClock вместо System.currentTimeMillis() или передавать обычный Clock как макет, потому что я надеялся, что смогу использовать функции тестирования виртуального времени reactor, но, похоже, это работает не так, как я ожидал.

Я делаю что-то не так? Как я могу получить «виртуальное» время в своем коде, чтобы сделать тестирование более приятным?

     @Test
    void testVirtualTimeWithSchedulerClock() {
        Flux<Integer> records = Flux.just(1, 2, 3, 4);
        List<Long> latencies = new ArrayList<>();

        StepVerifier.withVirtualTime(() -> {
            Clock clock = SchedulerClock.of(Schedulers.immediate());
            long start = clock.millis();
            return records.delayElements(Duration.ofSeconds(1))
                    .doOnNext(r -> {
                        long now = clock.millis();
                        long latency = now - start;
                        latencies.add(latency);
                    });
        })
        .expectSubscription()
        .expectNoEvent(Duration.ofSeconds(1))
        .expectNext(1)
        .expectNoEvent(Duration.ofSeconds(1))
        .expectNext(2)
        .expectNoEvent(Duration.ofSeconds(1))
        .expectNext(3)
        .thenAwait(Duration.ofSeconds(1))
        .expectNext(4)
        .expectComplete()
        .verify(VERIFIER_TIMEOUT);
        assertEquals(ImmutableList.of(1000L, 2000L, 3000L, 4000L), latencies);
        // FAIL: expected: <[1000, 2000, 3000, 4000]> but was: <[53, 53, 53, 53]>
    }
  

Ответ №1:

Я понял это, мне нужно было явно использовать VirtualTimeScheduler . Комментарии встроены ниже:

     @Test
void testVirtualTimeWithSchedulerClock() {
    Flux<Integer> records = Flux.just(1, 2, 3, 4);
    List<Long> latencies = new ArrayList<>();

    VirtualTimeScheduler scheduler = VirtualTimeScheduler.create(); // Need to create a scheduler
    StepVerifier.withVirtualTime(() -> {
        Clock clock = SchedulerClock.of(scheduler);                 // and use it here
        long start = clock.millis();
        return records.delayElements(Duration.ofSeconds(1))
                .doOnNext(r -> {
                    long now = clock.millis();
                    long latency = now - start;
                    latencies.add(latency);
                });
    }, () -> scheduler, 123123123L)                                 // and here
    .expectSubscription()
    .expectNoEvent(Duration.ofSeconds(1))
    .expectNext(1)
    .expectNoEvent(Duration.ofSeconds(1))
    .expectNext(2)
    .expectNoEvent(Duration.ofSeconds(1))
    .expectNext(3)
    .thenAwait(Duration.ofSeconds(1))
    .expectNext(4)
    .expectComplete()
    .verify(VERIFIER_TIMEOUT);
    assertEquals(ImmutableList.of(1000L, 2000L, 3000L, 4000L), latencies);
}