Reputation: 33618
There is a spring componet with @Component
annotation, it is just java class (not interface) with annotated @Autowired
fields. I am trying to create mock like that:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"
>
<bean id="myComponent" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="com.MyComponent"/>
</bean>
</beans>
And got an exception that some of fields are not autowired. This happens, because when Spring see <constructor-arg value="com.MyComponent"/>
it try to instantiate MyComponent
bean and pass it to factory method.
I have tried to extract interface from component, in that case mocking works, but is there a way to make it working without extracting interface?
Also
I have tried adding type="java.lang.Class"
but got same errors.
<bean id="myComponent" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg type="java.lang.Class" value="com.MyComponent"/>
</bean>
Any ideas?
Upvotes: 1
Views: 1510
Reputation: 16002
Spring cannot autowire the bean because the type of the created bean is java.lang.Object
and not com.myComponent
. Apparently the order of the definitions in the XML matters as well.
Jayway has a very nice blog post about this: Spring Integration Tests - Creating Mock Objects
You can create a FactoryBean
which returns the correct class:
public class MockitoFactoryBean<T> implements FactoryBean<T> {
private Class<T> classToBeMocked;
/**
* Creates a Mockito mock instance of the provided class.
* @param classToBeMocked The class to be mocked.
*/
public MockitoFactoryBean(Class<T> classToBeMocked) {
this.classToBeMocked = classToBeMocked;
}
@Override
public T getObject() throws Exception {
return Mockito.mock(classToBeMocked);
}
@Override
public Class<?> getObjectType() {
return classToBeMocked;
}
@Override
public boolean isSingleton() {
return true;
}
}
Using this factory bean, you can create a config like this:
<bean id="myComponent" class="com.yourpackage.MockitoFactoryBean">
<constructor-arg name="classToBeMocked" value="com.myComponent" />
</bean>
This will mock your component and the object type will com.myComponent
.
Update
This is the original answer and explanation (using EasyMock): Autowiring of beans generated by EasyMock factory-method?
Upvotes: 2