我们有一个使用Spring
注释来配置其上下文的项目。
要测试此项目,我们使用的是Mockito
和Spring
扩展程序。
在测试中,我需要使用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
的方式有什么问题?
答案 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,结果可能会令人困惑。