看起来我的测试不等待订阅 - webflux、spock、stepVerifier

问题描述 投票:0回答:1

我将我的问题简化为这个伪代码。 我的控制器

@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。当我运行该应用程序时,一切正常。我只有这个测试有问题。

java spring spring-boot spring-webflux spock
1个回答
0
投票

问题是所有动作都必须在

when
块内完成。尽管
result.verifyComplete()
可能看起来像一个简单的验证,实际上在这种情况下触发了对
Mono
的订阅。

现在,这与 Spock 的特性之一发生冲突,即

then
块中的所有交互都会首先断言,无论您在该块中编写其他检查的顺序如何。

所以实际发生的是这样的

  1. 您在
    when
    块中准备了Mono,但没有执行任何操作
  2. 模拟交互已验证,但失败,因为什么也没发生
  3. (步骤验证者将订阅并触发操作并验证结果)

要解决这个问题,应该这样写:

  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
  }
© www.soinside.com 2019 - 2024. All rights reserved.