Description
Dmitry Katsubo opened SPR-9130 and commented
Problem Area
I would like to have a myService
definition in both production and test application contexts so that the service is further autowired into other services. The test application context should create a mock version of the bean, e.g. by means of IMocksControl.createMock()
.
Current Approach
The test application context defines:
<!-- Common for all mocks: -->
<bean name="mockCtrl" class="org.easymock.EasyMock" factory-method="createStrictControl" />
<bean name="myService" factory-bean="mockCtrl" factory-method="createMock">
<constructor-arg value="org.company.api.MyService" />
</bean>
<!-- ... other mock definitions ... -->
The drawback of this approach is that the given service can no longer be autowired with @Autowired MyService myService
, but it can be injected with @Resource
.
Analysis
The reason that the mock cannot be autowired by type is that the parametrized return type of the method configured via factory-method
is not currently honored by Spring in all cases (i.e., depending on the order in which beans are defined in the context). In other words, the returned bean is not a candidate for autowiring by type for the type T
(i.e., org.company.api.MyService
in this example).
For a succinct discussion of this behavior, see the Explanation and Alternative solution sections of the Spring Integration Tests, Part I, Creating Mock Objects blog post.
Note that this is a general limitation of using factory-method
in Spring; this is not specific to testing or mocks.
Furthermore, the same naturally applies to other mocking frameworks such as Mockito.
Proposal
The solution is to use a specific FactoryBean
:
<bean name="myService" class="org.springframework.test.context.support.EasyMockFactoryBean"
p:mockInterface="org.company.api.MyService" />
Related Resources
- Spring Integration Tests, Part I, Creating Mock Objects (blog)
- EasyMock Objects Injection using Spring and Annotations (blog)
- Injecting Mockito mocks into a Spring bean (discussion at Stack Overflow)
- Mocking Spring beans (discussion at Stack Overflow)
- Springockito (open source project)
- spring-mvc-test with a sprinkle of mockito (blog)
Affects: 3.1 GA
Attachments:
- EasyMockBeanFactory.java (5.21 kB)
Issue Links:
- @Autowired dependencies against bean definitions with type-inspecific factory-methods may fail [SPR-8769] #13412
@Autowired
dependencies against bean definitions with type-inspecific factory-methods may fail - Infer return type of parameterized static factory methods [SPR-9493] #14127 Infer return type of parameterized static factory methods
- Return type prediction for generic factory method fails if type conversion of method arguments is necessary [SPR-10411] #15044 Return type prediction for generic factory method fails if type conversion of method arguments is necessary ("is superseded by")