1

How can I clear the application context after each test execution, with Junit5 and Spring Boot? I want all beans created in the test to be destroyed after its execution, since I am creating the same beans in multiple tests. I don't want to have one configuration class for all tests, but configuration class per test, as shown bellow.

@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = MyTest.ContextConfiguration.class)
public class MyTest{
   ...
   public static class ContextConfiguration {
     // beans defined here... 

   }
}

Putting @DirtiesContext(classMode = BEFORE_CLASS) doesn't work with Junit5.

Christina
  • 361
  • 1
  • 5
  • 17
  • 1
    did you try `@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)` – pvpkiran Feb 09 '18 at 09:12
  • It doesn't work. @pvpkiran – Christina Feb 09 '18 at 09:22
  • try this solution [Dirties Context](https://stackoverflow.com/questions/14718088/how-do-you-reset-spring-junit-application-context-after-a-test-class-dirties-it) – paul.anasuya Feb 09 '18 at 11:35
  • Why? The beans should be singletons and shouldn't keep state. The singleton nature is per application context (i.e. per combination of `classes` loaded with the `@ContextConfiguration`). Trying to recreate them each time will slow down your tests (Spring will cache the context between tests and when the same one comes around re-use it). – M. Deinum Feb 09 '18 at 11:59
  • For starters, your `MyTest.ContextConfiguration` class must be annotated with `@Configuration` for it to be considered a configuration class containing `@Bean` methods. – Sam Brannen Feb 10 '18 at 18:03
  • But I also have to agree with M. Deinum: why do you want to destroy the entire `ApplicationContext` after **every** test method? – Sam Brannen Feb 10 '18 at 19:38
  • Guys Dirties Context is not working for me too. Can someone help here? – R. Karlus Apr 26 '19 at 18:48

2 Answers2

7

You have claimed twice that @DirtiesContext(classMode = AFTER_EACH_TEST_METHOD) does not work; however, the following shows that it works as documented.

import javax.annotation.PreDestroy;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInfo;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.annotation.DirtiesContext.ClassMode;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;

@ExtendWith(SpringExtension.class)
@ContextConfiguration
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
class MyTest {

    @Test
    void test1(TestInfo testInfo) {
        System.err.println(testInfo.getDisplayName());
    }

    @Test
    void test2(TestInfo testInfo) {
        System.err.println(testInfo.getDisplayName());
    }

    @Configuration
    static class Config {

        @Bean
        MyComponent myComponent() {
            return new MyComponent();
        }
    }

}

class MyComponent {

    @PreDestroy
    void destroy() {
        System.err.println("Destroying " + this);
    }
}

Executing the above test class results in output to STDERR similar to the following.

test1(TestInfo)
Destroying MyComponent@dc9876b
test2(TestInfo)
Destroying MyComponent@30b6ffe0

Thus, @DirtiesContext(classMode = AFTER_EACH_TEST_METHOD) is indeed how you "clear the application context after each test execution".

Putting @DirtiesContext(classMode = BEFORE_CLASS) doesn't work with Junit5.

Based on my testing, classMode = BEFORE_CLASS works with TestNG, JUnit 4, and JUnit Jupiter (a.k.a., JUnit 5).

So, if that does not work in your test class, that would be a bug which you should report to the Spring Team.

Do you have any example where you can demonstrate that not working?

FYI: using classMode = BEFORE_CLASS would only ever make sense if the context had already been created within the currently executing test suite. Otherwise, you are instructing Spring to close and remove an ApplicationContext from the cache that does not exist... just before Spring actually creates it.

Regards,

Sam (author of the Spring TestContext Framework)

Sam Brannen
  • 29,611
  • 5
  • 104
  • 136
  • 1
    The problem is with @Nested classes. – R. Karlus Apr 26 '19 at 18:49
  • @RhuanKarlus, I recommend you ask a separate _question_ on Stack Overflow explaining what's not working with `@Nested` test classes. – Sam Brannen May 01 '19 at 13:30
  • See [@DirtiesContext does not work with @Nested tests](https://stackoverflow.com/questions/62142428/dirtiescontext-does-not-work-with-nested-tests) – Raedwald Oct 02 '20 at 23:34
1

According to the docs, try @DirtiesContext(classMode = AFTER_EACH_TEST_METHOD)

gWombat
  • 517
  • 2
  • 11