问题
在做单元测试引入Mockito的过程中,测试发送验证码接口,想使用mock的方式模拟调用短信服务发送验证码。测试类AppService依赖ConfigInfoSynchroHelper,
ConfigInfoSynchroHelper是调用短信的功能实现,AppService的UML图:
测试的过程中,发现如下使用
@Mock
private ConfigInfoSynchroHelper configInfoSynchroHelper;
@Autowired
@InjectMocks
private AppService appService;
测试appService发送验证码接口,都会调用configInfoSynchroHelper的实体实现方法,而不是mock;
经过调试,发现在AppService引入了类似@ShannonAuditLog(type = AuditType.APP_ADD)自定义注解,使用了AOP
在实例化AppService Bean的过程中,Spring做了一层封装,导致mock的configInfoSynchroHelper注入不成功。
解决方案
1. 在测试过程中,获取实例化AppServer去除Spring这层封装,在单元测试mock初始化之前执行以下代码:
appService = (AppService) unwrapProxy(appService);
public final Object unwrapProxy(Object bean) throws Exception {
/*
* If the given object is a proxy, set the return value as the object
* being proxied, otherwise return the given object.
*/
if (AopUtils.isAopProxy(bean) && bean instanceof Advised) {
Advised advised = (Advised) bean;
bean = advised.getTargetSource().getTarget();
}
return bean;
}
2. 使用@Bean的方式实例configInfoSynchroHelper
@Bean(name = “configInfoSynchroHelper”)
public ConfigInfoSynchroHelper getConfigInfoSynchroHelper() {
return configInfoSynchroHelper;
}
或者:
@Bean
public ConfigInfoSynchroHelper configInfoSynchroHelper() {
return configInfoSynchroHelper;
}