Why does this test fail?
import org.junit.jupiter.api.Test;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import reactor.core.publisher.Flux;
import reactor.test.StepVerifier;
import java.util.ArrayList;
import java.util.List;
public class StepVerifierTest {
@Test
void test() {
List<GrantedAuthority> roles = List.of(
new SimpleGrantedAuthority("user"),
new SimpleGrantedAuthority("admin")
);
StepVerifier.create(Flux.fromIterable(roles).map(GrantedAuthority.class::cast))
.recordWith(ArrayList::new)
.expectRecordedMatches(actualRoles -> actualRoles.containsAll(roles))
.expectComplete()
.verify();
}
}
java.lang.AssertionError: expectation "expectRecordedMatches" failed (expected collection predicate match; actual: [user])
For some reason, StepVerifier
put only the first element in the collection and then rushed to check the predicate. The documentation says
Start a recording session storing Subscriber.onNext(Object) values in the supplied Collection.
My expectation was that StepVerifier
would poll elements till the stream is exhausted and only then check the predicate
StepVerifier
's API doesn't suggest I should manually "record" emitted elements
Note please that this question is not about "how do I make the test pass". I know how
@Test
void test() {
List<GrantedAuthority> roles = List.of(
new SimpleGrantedAuthority("user"),
new SimpleGrantedAuthority("admin")
);
StepVerifier.create(Flux.fromIterable(roles).collectList())
.expectNextMatches(actualRoles -> actualRoles.containsAll(roles))
.expectComplete()
.verify();
/*
This, on the other hand, won't do since it asserts not only
on the content but also on the order of elements
StepVerifier.create(Flux.fromIterable(roles))
.expectNextSequence(roles)
.expectComplete()
.verify();
*/
}
Instead, I'm curious how that "recording" feature works
Put a count expectation between recordWith()
and expectRecordedMatches()
. I figure it trggers those onNext()
calls
@Test
void test() {
List<GrantedAuthority> roles = List.of(
new SimpleGrantedAuthority("user"),
new SimpleGrantedAuthority("admin")
);
StepVerifier.create(Flux.fromIterable(roles).map(GrantedAuthority.class::cast))
.recordWith(ArrayList::new)
.expectNextCount(2)
.expectRecordedMatches(actualRoles -> actualRoles.containsAll(roles))
.expectComplete()
.verify();
}
Simone Basle's way, I reckon, would be to do something like this (the guy's former lead at Project Reactor):
StepVerifier.create(Flux.fromIterable(roles).map(GrantedAuthority.class::cast))
.thenConsumeWhile(roles::contains)
.expectComplete()
.verify();
However, it passes even if the Flux
omits elements
StepVerifier.create(Flux.fromIterable(roles).take(1))
.thenConsumeWhile(roles::contains)
.expectComplete()
.verify();