Spring / Mock components that are retrieved by using the context directly
We have a project that uses Spring
annotations to configure its context. To test this project we are using Mockito
and it's Spring
extension.
In tests I need to override some beans with mock/spy version.
With the @Mock
/ @Spy
and @InjectMock
annotations I have been able to use spy for beans using autowiring mechanism.
Now I have a third party component which create another Spring context and then merge the 2 contexts together. This third party component retrieve beans using a call to the context:
applicationContext.getBean(key);
In this case, the @Mock/@Spy and @InjectMock combination is not working.
The 'workaround' solution I have put in place is an XML file in which I declare my spied bean:
<mockito:spy beanName="beanToSpy"/>
To stay in the annotation world, I have tried springockito-annotations as mentioned in these similar questions: Injecting Mockito mocks into a Spring bean and its duplicate: How to inject a Mock in a Spring Context
But the bean is not spied or mocked, I've probably a configuration error.
My current setup is:
A base class that is in charge of the Spring config for test:
@RunWith(SpringJUnit4ClassRunner.class)
@ActiveProfiles("test")
@ContextConfiguration(loader= SpringockitoContextLoader.class, locations ={"/config.xml","/test-config.xml"})
public abstract class BaseTest {
//...
}
A test class that would like to use a mocked 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();
}
}
Unfortunately in MyTest
, the beans are not replaced by their mock
/ spy
versions, it is the plain old regular version.
EDIT: The third party component that does the lookup is using its own spring parent context and add the current spring context into its own. The lookup to retrieve the component that I want to be mocked occurs after the context has been fully loaded.
What should I do to properly replace the bean in the context with a mock
/ spy
version ? What is wrong with the way I'm using @WrapWithSpy
/ @ReplaceWithMock
?
When does the call to
applicationContext.getBean(key);
happens? Is it possible that it retrieves the bean before the SpringockitoContextLoader has a chance to replace it with a spy?
One solution to stay in annotation world would be to override the bean in java config:
@Bean
public MyBeanType myBeanType() {
return spy(new MyBeanType(...))
}
The more conventional way to perform this is by simply mocking them in the test as required :
public class MyTest extends BaseTest {
@Test public void someTest() {
MyService myMockService = Mockito.mock(MyService.class);
// define when's
// perform verification
}
You can inject using SpringReflectionTestUtils, or if using setter injection just set normally.
If you use a global mocked bean in a test class with multiple tests, the results can get confusing.
链接地址: http://www.djcxy.com/p/82052.html上一篇: 如何在Spring上下文中注入模拟?