上两篇中,基本环境和测试方式都说了一下。基本的测试否没问题了。但是还有些问题需要解决。在我实际的开发中,最主要是是要做有Aop切面的Bean内部注入的bean打桩。
基本情况是:
MyService是个接口,其实现类MyServiceImpl是@Transactional注解的Bean(这样注入的MyService实例实际上就是代理了)
MyServiceImpl注了一个Bean:InnerBean,innerBean是自己工程中实现或其他服务都无所谓
测试中想使用mock替换这个InnerBean。
在spring中,aop用代理实现的。PowerMock不能修改其字节码。而在测试中,我需要替换MyService代理中的InnerBean实例。开始伤透了脑筋啊。。。
如果不能打桩,那么必须老老实实的准备fixture才能测试,比如准备数据库中多个表的数据,才能保证InnerBean完成我的预期结果(这种情况还算好的,有些情况都不能打桩)。
这个其实真是不难,只不过之前不太熟悉spring的测试框架(以前抛弃了spring,所以也不怎么研究)。
springtest有2个Utils类,可以帮助我们拿到MyService代理中的具体实现类:
org.springframework.test.util.AopTestUtils; org.springframework.test.util.ReflectionTestUtils;
MyServiceImpl impl = org.springframework.test.util.AopTestUtils.getTargetObject(MyServiceBean实例);
这样就可以拿到具体实现类了,再加一句impl.innerBean = mockInnerBean;就可以用自己打桩过的mock替换注入的innerBean实例了。如果多于一个测试方法,别忘了finally时候替换回来啊。
impl.innerBean 这里,我一般的注入bean都是是用package级别的,这样便于测试,不必特别的依赖其他技术就可以替换实现。如果是private的,那么用ReflectionTestUtils吧,具体不用说了,简单易用。