Frischling
Frischling

Reputation: 2268

StepVerifier expectNoEvent for 0ms does not work (want to check for no delay for special cases)

I have to create a per-customer backpressure, and implemented this with returning a Mono.justOrEmpty(authentication).delayElement(Duration.ofMillis(calculatedDelay));

This seems to be working fine in my unit-tests, BUT if I have a calculatedDelay of 0, I can't test this. This snippet returns a java.lang.AssertionError: unexpected end during a no-event expectation:

@Test
public void testSomeDelay_8CPUs_Load7() throws IOException {
  when(cut.getLoad()).thenReturn("7");
  when(cut.getCpuCount()).thenReturn(8L);
  when(authentication.getName()).thenReturn("delayeduser");

  Duration duration = StepVerifier
  .withVirtualTime(() -> cut.get(Optional.of(authentication))) 
  .expectSubscription()  // swallow subscribe event
  .expectNoEvent(Duration.ofMillis(0)) // here is the culprit
  .expectNextCount(1) 
  .verifyComplete(); 
}

I don't know how to check for the cases, where I'm expected no delay at all. This is BTW the same, when I return a Mono.justOrEmpty(authentication) (without any delayed subscription). I can't seem to check, that I have created the correct non-delayed flow.

Upvotes: 0

Views: 587

Answers (1)

Simon Baslé
Simon Baslé

Reputation: 28301

Yeah this is a corner case that is hard to cover. Especially when you know that foo.delayElement(0) is actually simply returning foo unmodified.

What you could do is test the delay differently, by appending an elapsed() operator:

Duration duration = StepVerifier
  .withVirtualTime(() -> cut.get(Optional.of(authentication))
     .elapsed() //this will get correct timing of 0 with virtual time
     .map(Tuple2::getT1) //we only care about the timing, T2 being the value
  ) 
  .expectNext(calculateDelay)
  .verifyComplete(); 

Upvotes: 2

Related Questions