【问题标题】:Mocked Objects in Context during tests execution测试执行期间上下文中的模拟对象
【发布时间】:2013-01-31 23:14:36
【问题描述】:

我正在开发一个同时具有组件和集成测试的应用程序。两者之间的区别是:组件测试测试多个类(即,它的内部对象并未全部模拟出来 - 但其中一些可能是 [例如 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) 标记集成测试,类中的第一个测试将失败,因为 SomeServiceInterface 被模拟 - 但下一个测试将通过,因为上下文已经刷新。

有趣的是:

如果我让 Spring 在集成测试中注入 SomeServiceInterface,它将注入 SomeServiceInterface 的具体实现——而不是模拟!

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

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

  2. 创建一个 TestExecution 侦听器,以便在执行 IntegrationTest 之前尝试手动刷新上下文

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

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

有人知道吗?

P.S.:我很理解采用 Springockito 是一个可疑的想法 - 但这个决定不是我做出的,现在我们在项目中有超过 500 个测试 - 因此重构它们以删除 Springockito 将是一项漫长的任务,因此它不是一个可行的选择 ATM。

【问题讨论】:

  • 8 年后:请参阅 Spring Boot 的 @MockBean 注释,它非常适合这个用例

标签: java spring testing mocking springockito


【解决方案1】:

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

【讨论】:

  • 是的,我知道那个监听器——我确实调试了代码,并且这个监听器调用了 testContext.markContextAsDirty()。我玩弄了侦听器并尝试创建一个自定义侦听器,在 Component Tests 完成后执行第一个 Integration Test 之前强制刷新 Spring 上下文。没用=(
【解决方案2】:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-12-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多