I would like to inject a Mockito mock object into a Spring (3+) bean for the purposes of unit testing with JUnit. My bean dependencies are currently injected by using the
I use a combination of the approach used in answer by Markus T and a simple helper implementation of ImportBeanDefinitionRegistrar
that looks for a custom annotation (@MockedBeans
) in which one can specify which classes are to be mocked. I believe that this approach results in a concise unit test with some of the boilerplate code related to mocking removed.
Here's how a sample unit test looks with that approach:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader=AnnotationConfigContextLoader.class)
public class ExampleServiceIntegrationTest {
//our service under test, with mocked dependencies injected
@Autowired
ExampleService exampleService;
//we can autowire mocked beans if we need to used them in tests
@Autowired
DependencyBeanA dependencyBeanA;
@Test
public void testSomeMethod() {
...
exampleService.someMethod();
...
verify(dependencyBeanA, times(1)).someDependencyMethod();
}
/**
* Inner class configuration object for this test. Spring will read it thanks to
* @ContextConfiguration(loader=AnnotationConfigContextLoader.class) annotation on the test class.
*/
@Configuration
@Import(TestAppConfig.class) //TestAppConfig may contain some common integration testing configuration
@MockedBeans({DependencyBeanA.class, DependencyBeanB.class, AnotherDependency.class}) //Beans to be mocked
static class ContextConfiguration {
@Bean
public ExampleService exampleService() {
return new ExampleService(); //our service under test
}
}
}
To make this happen you need to define two simple helper classes - custom annotation (@MockedBeans
) and a custom
ImportBeanDefinitionRegistrar
implementation. @MockedBeans
annotation definition needs to be annotated with @Import(CustomImportBeanDefinitionRegistrar.class)
and the ImportBeanDefinitionRgistrar
needs to add mocked beans definitions to the configuration in it's registerBeanDefinitions
method.
If you like the approach you can find sample implementations on my blogpost.