WebClient在JUnit中导致“ java.lang.IllegalStateException:执行程序不接受任务”

问题描述

我想在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);
}

因此,在这种情况下,该功能将等待任务完成。