在测试执行期间在上下文中模拟对象

时间:2013-01-31 23:14:37

标签: java spring testing mocking springockito

我正在开发一个同时具有组件和集成测试的应用程序。之间的区别在于:组件测试测试不止一个类(即,它的内部对象都没有被模拟 - 但是其中一些可能是[如JMS发布者])并且集成测试是一个测试什么都没有被嘲笑。换句话说,Spring为您提供了对象,并按原样测试它。

到目前为止,非常好。

问题是:为了能够从Spring上下文中替换一个或多个依赖项,我使用了Springockito(https://bitbucket.org/kubek2k/springockito/wiki/Home),它为您提供了一种从Spring上下文中模拟掉一些bean的方法。

所以 - 在组件测试中 - 我有这个:

@RunWith(SpringJUnit4ClassRunner.class)
@DirtiesContext(classMode = AFTER_CLASS)
@ContextConfiguration(loader = SpringockitoContextLoader.class, locations = "classpath:spring-classify-test.xml")
public class....

     @Autowired
     @ReplaceWithMock
     private SomeServiceInterface someServiceInterface;
     @Autowired
     private Bean bean;

Bean将SomeServiceInterface作为依赖。

public class Bean { 
   private SomeServiceInterface...

在上面的例子中,SomeServiceInterface将被mock替换。当然,这个例子是对问题的过度简化 - 我将bean替换为对象图中进一步向下依赖的模拟对象。

值得注意的是我从这个文件加载了上下文:spring-classify-test.xml同样,我注意到在执行类之后我将上下文标记为脏 - 所以, AFAIK,下一个测试类必须重新加载上下文。

好的,现在进行集成测试:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = SpringockitoContextLoader.class, locations = {"classpath:/spring-service-integration-test.xml" })
public class ...

    @Autowired
    private Bean bean;

我从spring-service-integration-test.xml加载上下文 - 但Bean内的SomeServiceInterface仍然被模拟!集成测试中使用的上下文也已更改!

如果我使用@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)标记Integration测试,则类中的第一个测试将失败,因为SomeServiceInterface被模拟 - 但下一个测试将通过,因为已经刷新了上下文。

有趣的是:

如果我要求Spring在Integration Test中注入SomeServiceInterface,它将注入一个SomeServiceInterface具体实现 - 而不是模拟!

我已经尝试了很多东西来解决这个问题:

1)在使用上下文中的registerBeanDefinition方法完成组件测试后,以编程方式覆盖上下文中的bean

2)创建一个TestExecution侦听器,这样我就可以尝试在执行IntegrationTest之前手动刷新上下文

3)对不同的上下文使用相同的加载器....

4)这个故事一直在继续。

有没有人有任何想法?

PS:我非常明白采用Springockito是一个可疑的想法 - 但这个决定不是我做的,现在我们在项目中有超过500个测试 - 因此重构它们以删除Springockito将是一个长期的任务,因此它不是一个可行的选择ATM。

干杯。

2 个答案:

答案 0 :(得分:1)

@DirtiesContext注释在DirtiesContextTestExecutionListener注册时由TestContextManager处理。使用普通的Spring测试,默认情况下会注册该侦听器。也许Springockito或你的测试“组件测试”中的其他东西正在做一些干扰默认监听器注册的事情?

答案 1 :(得分:0)

我建议使用

尝试最新的springockito-annotations 1.0.8
@DirtiesMocks(classMode = DirtiesMocks.ClassMode.AFTER_CLASS)

请参阅https://bitbucket.org/kubek2k/springockito/wiki/springockito-annotations#!reseting-mocksspies-in-experimental-package-hope-youll-like-it