Search code examples
javaspring-bootjunit

JUnit5 BeforeAllCallback is executed for every test class


I've the following classes:

public class MyExtension implements BeforeAllCallback, AfterAllCallback {
...
}

@SpringBootTest
@ExtendWith(MyExtension.class)
@ActiveProfiles("test")
class MyService1IT{
...
}

@SpringBootTest
@AutoConfigureMockMvc
@ExtendWith(MyExtension.class)
@ActiveProfiles("test")
class MyService2IT{
...
}

When executing the Tests with IntelliJ's Run All Tests or mvn failsafe:integration-test I can clearly see the beforeAll and afterAll method being executed for every class. How can I avoid this? I though ExtendWith would only be executed once for these callbacks.


Solution

  • No, the ExtendWith mechanism only allows you to design reusable behavior, but the lifecycle is very similar to @BeforeEach / @BeforeAll methods.

    But nothing stops you from implementing your own lifecycle in your extension. Here's some code that will make sure it's only called once.

    private static final AtomicBoolean FIRST_TIME = new AtomicBoolean(true);
    
    // and in your method:
    
    if(FIRST_TIME.getAndSet(false)){
        // code here that should only be run once
    }
    

    Note that this solution relies on being in the same VM / run. So if you have a fork mode per test or test class, you will need to use some external means of synchronization.