I simplified my problem to this pseudo code. My controller
@RestController
@RequestMapping("api")
@RequiredArgsConstructor
public class TestController {
private final Service service;
@PostMapping("/test")
public Mono<Void> test(@RequestBody @Valid Flux<TestDto> testDtoFlux) {
return testDtoFlux
.map(service::test)
.then();
}
test:
void setup() {
service = Mock(Service)
controller = new TestController(service)
}
def "Should test abc"() {
setup:
def testDto = new TestDto(11L, true)
when:
def result = StepVerifier.create(controller.test(Flux.just(testDto)))
then:
result
.verifyComplete()
1 * service.test(_) >> true
}
test everytime says that service.test
is never executed but when I changed code to something like this test passed:
public Mono<Void> test(@RequestBody @Valid Flux<TestDto> testDtoFlux) {
testDtoFlux
.map(service::test)
.then().block();
return Mono.empty();
}
I'm not sure why this is happening. I was trying to fix that with for example that:
result
.expectSubscription()
.thenAwait(Duration.ofSeconds(5))
.expectComplete()
.verify();
but result is always the same. Maybe you can see what I'm doing wrong?
ps. When I run the application, everything works fine. I only have a problem with this test.
The problem is that all actions must be completed inside the when
block. While
result.verifyComplete()
may look like a simple verification, it is actually what triggers the subscription to the Mono
in this case.
Now, this clashes with one of Spock's idiosyncrasies, namely that all interactions in a then
block are asserted first regardless of whatever order you write other checks in that block.
So what actually happens is that
when
block, but not action is performedTo fix the problem, it should be written like this:
def "Should test abc"() {
setup:
def testDto = new TestDto(11L, true)
when:
StepVerifier.create(controller.test(Flux.just(testDto)))
.verifyComplete()
then:
1 * service.test(_) >> true
}