Dzak
Dzak

Reputation: 213

How to test asynchronous method

I need to asynchronously fetch some data from DB, and then synchronously update currently cached data, with the one that was fetched.

At the moment my code looks like this:

@Asynchronous
public void fetchData() {
    CompletableFuture.supplyAsync(() -> {
        //Do some logic to fetch data
        return fetchedData;
    }).thenAccept(fetchedData -> updateCache(fetchedData));
}

My problem is that when I call this method in my tests, it instantly goes to thenAccept but fetchedData is empty. I've tried to change my method, and return CompletableFuture<List<Data>>, and call fetchData().join() in tests. It worked fine, but first - my app wouldn't build, since @Asynchronous need to return Future or void, and I don't think changing method just to test it is a good idea. I've heard about Await library, but can not use it in current project.

I'am also not sure, if @Asynchronous is needed in my case? If I'm not mistaken, CompletableFuture should run in own thread by default?

Upvotes: 1

Views: 275

Answers (2)

capo11
capo11

Reputation: 854

You can use this useful library: awaitility

Upvotes: 0

Sambit
Sambit

Reputation: 8021

Jacek, I think @Asynchronous annotation is not required. You can use the pure form of completable future. I provide below the sample code based upon the code you have provided.

public String getInfoFromDB() {
    try {
      TimeUnit.SECONDS.sleep(10);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    return "Data from DB";
  }

  public void updateCache(String dataFromDB) {
    System.out.println("Data from D : " + dataFromDB);
    System.out.println("Doing some operations with data from DB");
  }

  public void fetchData() {
    CompletableFuture cf =
        CompletableFuture.supplyAsync(() -> getInfoFromDB())
            .thenAccept(dataFromDB -> updateCache(dataFromDB));
    cf.join();
  }

Upvotes: 3

Related Questions