WebClient 在 JUnit 中导致 "java.lang.IllegalStateException: executor not accepting a task"

WebClient causes "java.lang.IllegalStateException: executor not accepting a task" in JUnit

我想在 JUnit 测试框架内使用反应式编程来对远程 rest 进行系统测试 api。

我这样写道:

  @Test
  void testWebClient() {
    WebClient webClient = WebClient.builder()
        .baseUrl(GITHUB_API_BASE_URL)
        .defaultHeader(HttpHeaders.CONTENT_TYPE, GITHUB_V3_MIME_TYPE)
        .defaultHeader(HttpHeaders.USER_AGENT, USER_AGENT)
        .filter(ExchangeFilterFunctions
            .basicAuthentication(appProperties.getGithub().getUsername(),
                appProperties.getGithub().getToken()))
        .build();

    var response = webClient.get()
        .uri("/user/repos?sort={sortField}&direction={sortDirection}",
            "updated", "desc")
        .exchange()
            .doOnError(e -> {
              System.out.println(e.toString());
            })
            .subscribe(r -> {
              System.out.println(r  );
            });
  }

获取我所有的 github 回购协议。我一直发现这个错误:

java.lang.IllegalStateException: executor not accepting a task

直到在“.exchange()”之后添加“.block()”以同步调用,一切开始正常工作。

我怀疑 JUnit 启动了一个特殊的线程上下文或类似的东西。你知道会发生什么吗?

非常感谢

问题是一旦函数 testWebClient() 完成,所有异步进程都将关闭。

在这种情况下,您使用的是异步作业 WebClient,因此函数 testWebClient()WebClient 可以得到答案之前完成。

为了防止这种情况,您可以:

  • 使用像TimeUnit.SECONDS.sleep(5)这样的线程休眠方法。
  • 使用外部库,例如 Awaitility

等待示例


bool taskDone = false;
@Test
void testWebClient() {
    //...
    var response = webClient.get()
    //...
    .doFinally(r->{
        taskDone = true;
    })

    await().until(()-> taskDone);
}

所以在这种情况下,函数将等待任务完成。

另一种选择是在您的测试用例中使用 StepVerifier。

    StepVerifier.create(<flux>)
      .expectSubscription()
      .consumeNextWith(e-> log.debug(e.toString()))      
      .thenAwait().verifyComplete();

将需要以下依赖项

    <dependency>
        <groupId>io.projectreactor</groupId>
        <artifactId>reactor-test</artifactId>
        <scope>test</scope>
    </dependency>