assertj: assertThat with CompletionStage is not waiting CompletableFuture to complete

Summary

I’m trying to do some test with firebase SDK things, the problem that the assertThat always failing with message:

[error] Expecting [error] <CompletableFuture[Incomplete]> [error] to be completed. [error] Be aware that the state of the future in this message might not reflect the one at the time when the assertion was per formed as it is evaluated later on, took 0.145 sec

and I’m not sure how to make it wait, I can do just a stupid solution with .join() to make it work, but really it is not something that I’m looking for with this case.

Example

I have the following method of my service:

    /**
     * @param email
     * @return token
     */
    public CompletableFuture<String> getCustomToken(String email) {
        CompletableFuture<String> future = new CompletableFuture<>();
        ApiFuture<UserRecord> emailAsync = firebaseAuthProvider.get().getUserByEmailAsync(email);

        emailAsync.addListener(() -> {
            try {
                UserRecord userRecord = emailAsync.get();
                if (userRecord != null && userRecord.getUid() != null) {
                    ApiFuture<String> customTokenAsync = firebaseAuthProvider.get().createCustomTokenAsync(userRecord.getUid());
                    customTokenAsync.addListener(() -> {
                        try {
                            future.complete(customTokenAsync.get());
                        } catch (InterruptedException | ExecutionException e) {
                            future.completeExceptionally(e);
                        }
                    }, ec.current());
                } else {
                    future.completeExceptionally(new BusinessException(MsgKeys.ERR_USER_UID_NOT_FOUND));
                }
            } catch (InterruptedException | ExecutionException exception) {
                logger.error(exception.getMessage());
                future.completeExceptionally(new BusinessException(MsgKeys.ERR_VALIDATE_TOKEN_FAILED, exception.getCause()));
            }
        }, ec.current());
        return future;
    }

Then This is the test method:

    @Test
    public void testLoginWithCustomTokenMustFailWithVerifyIdToken() {
        logger.info("Testing login, we will create a custom token then verify it, it should be success until reach verifyIdToken and fail, because we can only verifyIdToken with " +
                "tokens from frontend");
        String email = config.getString("firebase.test.email");
        CompletionStage<String> tokenFuture = firebaseAuthService.getCustomToken(email);
        logger.info("Testing creating custom token for email " + email);

        assertThat(tokenFuture).isCompletedWithValueMatching(token -> {
            JsonNode jsonNode = Json.newObject().put("token", token);
            logger.info("Trying to verify token " + token);

            exception.expectCause(allOf(Matchers.instanceOf(FirebaseAuthException.class), hasProperty("message", startsWith("verifyIdToken() expects an ID token, but was given a custom token"))));
            Http.RequestBuilder request = Helpers.fakeRequest()
                    .method(POST)
                    .bodyJson(jsonNode)
                    .uri("/api/user/firebaseLogin");

            Result route = route(app, request);
            return route.status() == 200;
        }, "Creating custom token for " + email);

    }

But when I replace CompletionStage<String> tokenFuture = firebaseAuthService.getCustomToken(email); with CompletionStage<String> tokenFuture = CompletableFuture.completedFuture(firebaseAuthService.getCustomToken(email).join()); it will work.

Is it my code issue, or test not waiting correctly, or am I missing something?

Evironment:

Java 8 & 10:

java version “1.8.0_162” Java™ SE Runtime Environment (build 1.8.0_162-b12) Java HotSpot™ 64-Bit Server VM (build 25.162-b12, mixed mode)

java 10 2018-03-20 Java™ SE Runtime Environment 18.3 (build 10+46) Java HotSpot™ 64-Bit Server VM 18.3 (build 10+46, mixed mode)

Play Framework (2.6.x): https://www.playframework.com/documentation/2.6.x/JavaFunctionalTest SBT: 0.13.15 AssertJ 3.9.1: libraryDependencies += "org.assertj" % "assertj-core" % "3.9.1" % Test

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Reactions: 1
  • Comments: 16 (11 by maintainers)

Commits related to this issue

Most upvoted comments

forgotten mostly, now that we have added succeedsWithin for 3.17.0 https://github.com/joel-costigliola/assertj-core/pull/1930, we should add failsWithin too

The succeedsWithin/failsWithin pair seems a good option to me