【问题标题】:Spring bean autowire for testing用于测试的 Spring bean autowire
【发布时间】:2013-07-15 09:09:15
【问题描述】:

我有很多使用这个 autowire 的 spring 服务:

@Autowired
private SmartCardService smartCardService;

我需要一个用于测试的虚拟类,并且我定义了这个类来扩展原始类:

@Service
public class DummySmartCardService extends SmartCardService{
    ...
}

在不更改所有 Autowired 注释的情况下,如何确保所有 autowire 都将采用 dummy 而不是原始服务?

谢谢。

【问题讨论】:

  • 这也是我偏爱XML配置的原因。

标签: java spring testing autowired


【解决方案1】:

考虑使用@Primary 注解。见here

【讨论】:

    【解决方案2】:

    从您的应用程序上下文文件的测试版本中加载您的 DummySmartCardService bean,这样就无需更改被测代码

    @ContextConfiguration(locations = {"classpath:test-services.xml"})
    

    【讨论】:

      【解决方案3】:

      使用@Resource 注解或@Qualifier,与区分bean 类型的@Qualifier:

      @Autowired
      @Qualifier("testing")
      private SmartCardService smartCardService;
      
      @Service
      @Qualifier("testing")
      public class DummySmartCardService extends SmartCardService{
          ...
      }
      

      或者使用使用按名称语义的@Resource:

      @Resource("dummySmartCardService")
      private SmartCardService smartCardService;
      
      
      @Service("dummySmartCardService")
      public class DummySmartCardService extends SmartCardService{
          ...
      }
      

      理论上您可以使用@Qualifier("beanName"),但不鼓励使用。

      但如果你有一个 Spring 配置文件来在你的测试中只加载与测试相关的存根,它认为会更好:

      @Service
      @Profile("test")
      public class DummySmartCardService extends SmartCardService{
          ...
      }
      
      @ContextConfiguration(locations = {"classpath:services.xml"})    
      @ActiveProfiles("test")
      public class TestSuite{
          @Autowired
          private SmartCardService smartCardService;
      }
      

      【讨论】:

      • @ŁukaszLech 是的,我有时更喜欢 xml,但知道如何使用注解并没有错。
      • 问题是我需要更改所有@Autowired 注释
      • @ŁukaszLech 我认为使用资源注释您只需要更改一个,不是吗?我认为有时使用 XML 过于冗长:你是否也将 Spring MVC 与 XML 一起使用?
      • @mael 使用 XML 编写一次,使用注释每次修改代码以运行测试,至少在这种情况下是这样。
      • @ŁukaszLech 在这种情况下还有注释,你只需要更好地计划它;)
      【解决方案4】:

      恕我直言,您应该查看 Springockio 以正确且相当容易地模拟 Spring bean。

      您可以通过这种方式将 bean 替换为 mock 或使用 Spy 包装:

      @ContextConfiguration(loader = SpringockitoContextLoader.class,
      locations = "classpath:/context.xml")
      public class SpringockitoAnnotationsMocksIntegrationTest extends 
                                      AbstractJUnit4SpringContextTests {
      
          @ReplaceWithMock
          @Autowired
          private InnerBean innerBean;
      
          @WrapWithSpy
          @Autowired
          private AnotherInnerBean anotherInnerBean;
          ....
      }
      

      这不仅是一种简洁的方式(您不需要通过添加限定符或配置文件来更改正在测试的代码)而且还允许您使用Mockito 的功能进行模拟、验证和间谍,这很棒。

      【讨论】:

      • 理论上很好,实际上这个项目有很多烦人的错误。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-22
      • 2015-09-02
      • 1970-01-01
      相关资源
      最近更新 更多