通过直接使用上下文检索的Spring / Mock组件

时间:2014-06-20 11:39:52

标签: java spring testing mockito

我们有一个使用Spring注释来配置其上下文的项目。 要测试此项目,我们使用的是MockitoSpring扩展程序。

在测试中,我需要使用mock / spy版本覆盖一些bean。

使用@Mock / @Spy@InjectMock注释,我可以使用自动装配机制将bean用于间谍。

现在我有了第三方组件,它创建了另一个Spring上下文,然后将两个上下文合并在一起。此第三方组件使用对上下文的调用来检索bean:

applicationContext.getBean(key);

在这种情况下,@ Mock / @ Spy和@InjectMock组合无效。

我已经实施的“解决方法”解决方案是一个XML文件,我在其中声明了我的spied bean:

<mockito:spy beanName="beanToSpy"/>

为了留在注释世界,我尝试了springockito-annotations,就像这些类似问题中所提到的那样: Injecting Mockito mocks into a Spring bean 及其副本: How to inject a Mock in a Spring Context

但bean没有被发现或嘲笑,我可能是配置错误。

我目前的设置是:

负责测试的Spring配置的基类:

@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("test")
@ContextConfiguration(loader= SpringockitoContextLoader.class, locations ={"/config.xml","/test-config.xml"})
public abstract class BaseTest {
  //...
}

想要使用模拟bean的测试类:

public class MyTest extends BaseTest {
  @ReplaceWithMock @Autowired MyService myService;
  @WrapWithSpy @Autowired OtherService otherService;

  @Test public void someTest() { 
    doReturn(x).when(myService).call();
    doReturn(y).when(otherService).process();
  }
}

不幸的是,在MyTest中,bean没有被mock / spy版本取代,它是普通的常规版本。

编辑: 执行查找的第三方组件使用自己的spring父上下文,并将当前的spring上下文添加到其自己的中。在完全加载上下文之后,查找以检索我想要模拟的组件。

如何使用mock / spy版本正确替换上下文中的bean? 我使用@WrapWithSpy / @ReplaceWithMock的方式有什么问题?

2 个答案:

答案 0 :(得分:1)

何时调用

applicationContext.getBean(key);

会发生什么?是否有可能在SpringockitoContextLoader有机会用间谍替换它之前检索bean?

留在注释世界的一个解决方案是在java config中覆盖bean:

@Bean
public MyBeanType myBeanType() {
    return spy(new MyBeanType(...))
}

答案 1 :(得分:0)

执行此操作的更常规方法是根据需要在测试中简单地模拟它们:

public class MyTest extends BaseTest {
    @Test public void someTest() { 
        MyService myMockService = Mockito.mock(MyService.class);
        // define when's
       // perform verification
      }

你可以使用SpringReflectionTestUtils注入,或者如果使用setter注入只是正常设置。

如果在具有多个测试的测试类中使用全局模拟bean,结果可能会令人困惑。