Spring Boot reactor 测试如何使用 StepVerifier 记录和检查 Flux<String> 的测试包含字符串

问题描述

我有一个 Spring Boot 测试,其中的代码创建了一个简单的 Flux<String 异步结果。我想测试是否有包含字符串 price 的结果。代码是这样的:

@SpringBoottest
@ContextConfiguration(classes = PriceTests.class)
public class PriceTests {

@Autowired
RestController controller;

    @Test
    public void DoPriceTests() throws InterruptedException
    {
        Flux<String> prices = controller.getPrices();

        Logs.Info("Test prices");  

        StepVerifier.create(prices)
        .expectNextMatches(s -> s.contains("price"))
        .expectComplete()
        .verify(Duration.ofSeconds(3));
    }
}

问题是我注意到当没有价格时,测试仍然通过!那不应该发生。我如何log expectNextMatches 字符串?例如,类似这样的事情,它会显示每个价格的 Flux<String> 的实际值是多少:

StepVerifier.create(prices)
  .expectNextMatches(s -> {
      Logs.Info(s);
      s.contains("price");
  })
  .expectComplete()
  .verify(Duration.ofSeconds(3));

解决方法

最后一些答案,要么使用 blockfirstStepVerifier 订阅 Flux,然后在 String 数据上使用常规 Hamcrest 断言。在测试完成前给出 3 秒的超时时间。

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.CoreMatchers.containsString;
// Other imports

@SpringBootTest
@ContextConfiguration(classes = PriceTests.class)
public class PriceTests {

@Autowired
RestController controller;

@Test
public void UseBlock() throws InterruptedException
{
    Flux<String> prices = controller.getPrices();

    Logs.Info("Test prices");  

    // Using block
    String myPrice = prices.blockFirst(Duration.ofSeconds(3));        
    Logs.Info(myPrice);
    assertThat(myPrice,containsString("price"));
}

@Test
public void UseStepVerifier() throws InterruptedException
{
    Flux<String> prices = controller.getPrices();

    Logs.Info("Test prices");  

    // Using StepVerifier
    StepVerifier.create(prices)
        .assertNext(s -> 
        {
            Logs.Info(s);
            assertThat(s,containsString("price"));
        })
        .thenCancel()
        .verify(Duration.ofSeconds(3));
}