javaspringspring-securityautomated-testsawaitility

How to Use Awaitility with Authentication Context in Spring Boot Integration Tests?


I'm facing an issue with using Awaitility in my Spring Boot integration tests. My setup involves setting an authentication context in the test before executing a piece of code that I want to verify with Awaitility. However, since Awaitility runs the predicate on a different thread, it cannot access the authentication context I have set up, causing my tests to fail.

Here is a simplified version of my code:

@Test
public void testMyServiceWithAuthentication() {
    // Logging in user


    myService.performAction();

    // Use Awaitility to wait for a condition
    await().atMost(10, SECONDS).until(() -> {
        // This predicate runs in a different thread, so it cannot access the authentication context
        return myService.checkCondition();
    });
}

When the Awaitility predicate runs, it does not have access to the authentication context set up in the main test thread, so myService.checkCondition() fails due to missing authentication.

My Question: Is there a way to ensure that the authentication context is available to the Awaitility predicate when running in a Spring Boot integration test? Or is there an alternative approach for waiting on a condition that relies on authentication within the same thread?


Solution

  • Awaitility supports that use-case with ConditionFactory#pollInSameThread

    Instructs Awaitility to execute the polling of the condition from the same as the test. This is an advanced feature and you should be careful when combining this with conditions that wait forever (or a long time) since Awaitility cannot interrupt the thread when it's using the same thread as the test. For safety you should always combine tests using this feature with a test framework specific timeout

    It should work similar to this for your example code:

        await().pollInSameThread().atMost(10, SECONDS).until(myService::checkCondition);