我将我的问题简化为这个伪代码。 我的控制器
@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();
}
测试:
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
}
测试每次都说
service.test
永远不会执行,但是当我将代码更改为类似这样的测试时,测试通过了:
public Mono<Void> test(@RequestBody @Valid Flux<TestDto> testDtoFlux) {
testDtoFlux
.map(service::test)
.then().block();
return Mono.empty();
}
我不确定为什么会发生这种情况。我试图解决这个问题,例如:
result
.expectSubscription()
.thenAwait(Duration.ofSeconds(5))
.expectComplete()
.verify();
但结果总是一样的。也许你能看出我做错了什么?
ps。当我运行该应用程序时,一切正常。我只有这个测试有问题。
问题是所有动作都必须在
when
块内完成。尽管
result.verifyComplete()
可能看起来像一个简单的验证,实际上在这种情况下触发了对 Mono
的订阅。
现在,这与 Spock 的特性之一发生冲突,即
then
块中的所有交互都会首先断言,无论您在该块中编写其他检查的顺序如何。
所以实际发生的是这样的
when
块中准备了Mono,但没有执行任何操作要解决这个问题,应该这样写:
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
}