测试后清除 Spring 应用程序上下文

Chr*_*ina 0 junit spring spring-test applicationcontext junit5

如何在每次测试执行后使用 Junit5 和 Spring Boot 清除应用程序上下文?我希望在测试中创建的所有 bean 在执行后都被销毁,因为我在多个测试中创建了相同的 bean。我不想为所有测试使用一个配置类,而是每个测试都有一个配置类,如下所示。

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

   }
}
Run Code Online (Sandbox Code Playgroud)

Putting@DirtiesContext(classMode = BEFORE_CLASS)不适用于 Junit5。

Sam*_*nen 5

您已经申请两次@DirtiesContext(classMode = AFTER_EACH_TEST_METHOD)无效;但是,以下内容表明它按文档工作。

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

执行上述测试类会导致输出到STDERR,类似于以下内容。

test1(TestInfo)
Destroying MyComponent@dc9876b
test2(TestInfo)
Destroying MyComponent@30b6ffe0
Run Code Online (Sandbox Code Playgroud)

因此,@DirtiesContext(classMode = AFTER_EACH_TEST_METHOD)这确实是您“在每次测试执行后清除应用程序上下文”的方式。

Putting@DirtiesContext(classMode = BEFORE_CLASS)不适用于 Junit5。

根据我的测试,classMode = BEFORE_CLASS可以使用 TestNG、JUnit 4 和 JUnit Jupiter(又名 JUnit 5)。

因此,如果这在您的测试类中不起作用,那将是一个错误,您应该向 Spring 团队报告

你有什么例子可以证明它不起作用吗?

仅供参考:classMode = BEFORE_CLASS只有在当前执行的测试套件中已经创建了上下文时,使用才有意义。否则,您将指示 Spring 关闭并ApplicationContext从缓存中移除不存在的 ...... 就在 Spring 实际创建它之前。

问候,

Sam(Spring TestContext Framework 的作者