【问题标题】:How to override the behavior of Spring @Autowired如何覆盖 Spring @Autowired 的行为
【发布时间】:2010-05-16 10:01:27
【问题描述】:

一点背景:

我正在使用 Spring 2.5,特别是 Spring IOC 和注释。

我在我的代码中使用@Autowired(自动装配是按类型完成的) 并使用@Component 将类公开给自动布线。

当我尝试测试我的代码时,出现了下面描述的情况。

现在问题来了:

注意:我为测试环境使用了不同的 Spring 上下文。

我有一个FOO 的类@Autowired,但在测试上下文中我想使用相同类型的不同类MockFoo(扩展FOO)。

由于FOO 类的依赖注入的多个选项(FOOMockFOO 都符合类型检查),Spring 设置当然会自动失败。

我正在寻找一种方法来注入测试 bean 而不是原始 bean。

我希望 Spring 允许使用上下文配置文件来覆盖 bean 注入或命令 Spring 不自动装配特定的 bean。

但是

所有这些选项似乎只存在于最初在 Spring 上下文配置文件中定义的 bean。

【问题讨论】:

    标签: unit-testing spring dependency-injection


    【解决方案1】:

    使用ReflectionTestUtils 手动设置 Mock 以代替自动装配的依赖项(为此,您的 mock 不得由 spring 管理,以免存在歧义)

    【讨论】:

    • 当您没有将相同的实例注入多个类时,这是一个很好的解决方案 - 但在一个类充当服务提供者(它是单例)并被注入到许多类的大型项目中类,我希望有一些更简单/更好的解决方案来避免注入每个使用原始类的类
    【解决方案2】:

    我知道这个问题已经很老了,但我认为答案可能对其他人仍然有用。

    由于您可能不想在您的上下文中同时混合 Foo 和 MockFoo,我建议从组件扫描中删除 Foo。例如,这可以通过在 <context:component-scan> 上指定 include/exclude filters 来完成。

    但是,如果您要实现单元测试,我宁愿建议不要使用 Spring 上下文,而只是通过手动注入依赖项的模型来实现“纯”单元测试,这样您就只测试一个类。这可以通过使用像 Mockito 这样的模拟框架更轻松地实现。

    【讨论】:

      【解决方案3】:

      我同意迪迪埃的观点。下面是一个示例,说明如何排除要在测试应用程序上下文中模拟的实现。

      <context:component-scan base-package="com.company" >
          <context:exclude-filter type="regex" expression="com\.abc\.service\.XDaoImpl"/>    
      </context:component-scan>
      

      在您的测试中包含此应用程序上下文,如下所示:

      @RunWith(SpringJUnit4ClassRunner.class)
      @ContextConfiguration(locations={"classpath:/applicationContext-test.xml"})
      public class MyTest {....}
      

      【讨论】:

      • 好答案,我真的会选择这个。不要忘记,您始终可以在要注入的 bean 上使用 @Qualifier(name="someBean") 并在要注入特定 bean 实例的字段上使用 @Resource(name="someBean")。跨度>
      猜你喜欢
      • 2015-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多