Reply to comment
EasyMock Objects Injection using Spring and Annotations
Submitted by rowell on Tue, 08/11/2009 - 01:00Declaring EasyMock objects as spring beans is easy...
<bean id="mailProcessor" class="org.easymock.classextension.EasyMock" factory-method="createMock">
<constructor-arg value="com.myservice.MailProcessor" />
</bean>
<constructor-arg value="com.myservice.MailProcessor" />
</bean>
However, if the bean you want to test is dynamically proxied, you will get a ClassCastException. To work around this, you can create a custom annotation and bean post processor. This will allow you to annotate fields with @MockObject and Spring will provide the mock object using dependency injection...
Custom Annotation
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
@Documented
public @interface MockObject {}
@Target({ElementType.FIELD})
@Documented
public @interface MockObject {}
Custom Spring Bean Post Processor
@Component
public class MockObjectBeanPostProcessor implements BeanPostProcessor
{
private Log logger = LogFactory.getLog(this.getClass());
/* (non-Javadoc)
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization
*/
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException
{
// get all the fields
Field[] fields = bean.getClass().getDeclaredFields();
for(Field field : fields)
{
// check if field is annotated by Environment Property
if(field.isAnnotationPresent(MockObject.class))
{
try
{
field.setAccessible(true);
field.set(bean, EasyMock.createMock(field.getType()));
} catch (Exception e) {
logger.warn(e);
}
}
}
return bean;
}
/* (non-Javadoc)
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization
*/
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException
{
// do nothing, return original bean
return bean;
}
}
public class MockObjectBeanPostProcessor implements BeanPostProcessor
{
private Log logger = LogFactory.getLog(this.getClass());
/* (non-Javadoc)
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessBeforeInitialization
*/
public Object postProcessBeforeInitialization(Object bean, String beanName)
throws BeansException
{
// get all the fields
Field[] fields = bean.getClass().getDeclaredFields();
for(Field field : fields)
{
// check if field is annotated by Environment Property
if(field.isAnnotationPresent(MockObject.class))
{
try
{
field.setAccessible(true);
field.set(bean, EasyMock.createMock(field.getType()));
} catch (Exception e) {
logger.warn(e);
}
}
}
return bean;
}
/* (non-Javadoc)
* @see org.springframework.beans.factory.config.BeanPostProcessor#postProcessAfterInitialization
*/
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException
{
// do nothing, return original bean
return bean;
}
}
Sample JUnit Test
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/spring-test.xml"})
public class MailProcessorTest
{
@MockObject private MailProcessor mailProcessor;
@Test
public void test()
{
// setup test behavior
EasyMock.replay(mailProcessor);
}
}
@ContextConfiguration(locations={"/spring-test.xml"})
public class MailProcessorTest
{
@MockObject private MailProcessor mailProcessor;
@Test
public void test()
{
// setup test behavior
EasyMock.replay(mailProcessor);
}
}