Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I wanted to use reactive programming inside the JUnit testing framework to do system tests on a remote rest api.

I thus wrote:

  @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  );
            });
  }

to get all my github repos. I kept catching this error:

java.lang.IllegalStateException: executor not accepting a task

until add ".block()" after ".exchange()" to do the call synchronously and everything start to work fine.

I suspect JUnit to start a special thread context or something like that. Do you know what can is happening?

Thanks a lot

like image 921
Guillaume Blanchet Avatar asked Oct 31 '25 01:10

Guillaume Blanchet


1 Answers

The problem is that once the function testWebClient() finish, all the asynchronous process are closed.

In this case you are using WebClient that is an async job, so the function testWebClient() finish before the WebClient can get the answer.

In order to prevent this, you can:

  • use a thread sleep method like TimeUnit.SECONDS.sleep(5).
  • use an external library like Awaitility

Example with Awaitility


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

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

So in this case the function will wait until the task complete.

like image 177
David A. Avatar answered Nov 02 '25 15:11

David A.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!