【问题标题】:removing singleton beans from context during the test在测试期间从上下文中删除单例 bean
【发布时间】:2015-02-02 04:47:47
【问题描述】:

我有一个使用 spring-REST(spring 版本 4.1.x 编写的应用程序,并且正在使用 spring test 对其进行测试。其中一个单例 bean 正在缓存状态,以便它可以用于应用程序中的后续调用。这个虽然在我运行多个测试时会导致问题,因为跨测试使用同一个bean并且后续测试失败。我的问题是如何在拆卸中重置状态? 状态作为类的私有成员是不可访问的。我们可以从上下文中完全删除 bean 吗?我在需要时使用带注释的 bean 和自动装配。

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@ContextConfiguration(classes = ComponentTestConfig.class)
public class WebServiceComponentTest {

}

我尝试使用以下链接中给出的解决方案 How can i remove a singleton spring bean from ApplicationContext?

但总是因为找不到 bean 定义而失败 ((BeanDefinitionRegistry) beanFactory).removeBeanDefinition("myBean");

顺便说一句,只有在需要拆卸以重置 bean 状态时测试才会失败。在应用程序使用 Bean 时找到它。

【问题讨论】:

  • @DirtiesContext注释你的测试(或测试类),这会让你从一个新的应用程序上下文开始。
  • 我在一个stackoverflow问题中看到了。这应该很少使用,它会减慢你的测试速度。我想避免降低测试性能。因为它根据 CI 管道为每次签入运行...有没有更好的方法来修复它?
  • 这是实现您想要的唯一保存和可靠的方法,也许重新考虑您迄今为止构建的内容,而不是使用您自己的缓存机制,而是使用基于 Spring 的缓存机制(您可以禁用它某些测试)。

标签: spring spring-mvc spring-integration spring-test


【解决方案1】:

如果您想对测试应用程序上下文进行更细粒度的控制,请镜像您的 XML 配置文件以进行测试。将您的测试类指定为仅从您的测试目录而不是从您的 WebContent 目录加载 XML 文件。

这样您就可以从测试上下文中完全排除导致您出现问题的类。所以你的测试 XML 可能看起来像这样:

<context:component-scan base-package = 
    "au.com.foo.pineapple", 
    "au.com.foo.dolphin",
    "au.com.foo.controllers"
/>
<!--au.com.foo.building-->

您的 WebContent XML 文件可能如下所示:

<context:component-scan base-package =
    "au.com.foo.pineapple",
    "au.com.foo.dolphin",
    "au.com.foo.building",
    "au.com.foo.controllers"
/>

【讨论】:

    【解决方案2】:

    正如 M. Deinum 指出的那样,实现此目的最安全的方法是使用 @DirtiesContext 注释。

    但是,正如也提到的,使用 @DirtiesContext 可能会导致更长的测试运行时间,因为 ApplicationContext 将从 ContextCache 中删除。

    另一种选择——真正的hack——是使用spring-test 中的ReflectionTestUtils 类来更改相关私有成员的状态。

    问候,

    Sam(Spring TestContext 框架的作者

    【讨论】:

      猜你喜欢
      • 2018-05-31
      • 1970-01-01
      • 1970-01-01
      • 2019-09-12
      • 2011-10-14
      • 1970-01-01
      • 2018-04-03
      • 2023-04-10
      • 1970-01-01
      相关资源
      最近更新 更多