【问题标题】:Clear Spring application context after test测试后清除 Spring 应用程序上下文
【发布时间】:2018-07-20 00:20:15
【问题描述】:

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

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

   }
}

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

【问题讨论】:

  • 你试过@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
  • 它不起作用。 @pvpkiran
  • 试试这个解决方案Dirties Context
  • 为什么? bean 应该是单例并且不应该保持状态。单例性质是每个应用程序上下文(即每个classes@ContextConfiguration 的组合)。每次都尝试重新创建它们会减慢您的测试速度(Spring 将缓存测试之间的上下文,并在相同的测试出现时重新使用它)。
  • 对于初学者,您的MyTest.ContextConfiguration 类必须使用@Configuration 进行注释,才能将其视为包含@Bean 方法的配置类。

标签: spring junit spring-test applicationcontext junit5


【解决方案1】:

根据docs,试试@DirtiesContext(classMode = AFTER_EACH_TEST_METHOD)

【讨论】:

  • 你的 Spring 版本是什么?
【解决方案2】:

您曾两次声称@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);
    }
}

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

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

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

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

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

因此,如果这在您的测试类中不起作用,那将是一个错误,您应该 report to the Spring Team

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

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

问候,

Sam(Spring TestContext 框架的作者

【讨论】:

猜你喜欢
  • 2012-10-28
  • 1970-01-01
  • 2012-01-20
  • 1970-01-01
  • 2018-01-20
  • 1970-01-01
  • 2013-02-03
  • 2018-07-11
相关资源
最近更新 更多