MockIto+Spring測試抽象類中的方法
使用場景:
抽象類AManager.class中的實現方法getSomeThing()的測試
由於是在SpringBoot的項目中,首先引入SpringBoot的測試註解
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Bootstrap.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@DirtiesContext
public class AManagerTest{
...}
然後對getSomeThing()中的外部方法的調用和AManager類的成員變量進行Mock
//通過Mockito對抽象類進行mock
AManager aManager = Mockito.mock(AManager.class, Mockito.CALLS_REAL_METHODS);
File file = Mockito.mock(File.class);
RedisService redisServicemock = Mockito.mock(RedisService.class);
//通過反射獲取到需要替換的成員變量 f--變量名
Field testField = AManager.class.getDeclaredField("f");
testField.setAccessible(true);
testField.set(aManager, file);
通過Mockito.when(…).thenReturn(true);對mock的成員變量或者類對象的方法設置返回值
Mockito.when(file.exists()).thenReturn(true);
對抽象類中對Spring容器中託管的類對象的替換
先給出AopTargetUtils這個抽象類,來自大神的博客
package com.zm_recordUser;
import org.springframework.aop.framework.AdvisedSupport;
import org.springframework.aop.framework.AopProxy;
import org.springframework.aop.support.AopUtils;
import java.lang.reflect.Field;
public class AopTargetUtils {
/**
* 獲取 目標對象
* @param proxy 代理對象
* @return
* @throws Exception
*/
public static Object getTarget(Object proxy) throws Exception {
if(!AopUtils.isAopProxy(proxy)) {
return proxy;//不是代理對象
}
if(AopUtils.isJdkDynamicProxy(proxy)) {
return getJdkDynamicProxyTargetObject(proxy);
} else { //cglib
return getCglibProxyTargetObject(proxy);
}
}
private static Object getCglibProxyTargetObject(Object proxy) throws Exception {
Field h = proxy.getClass().getDeclaredField("CGLIB$CALLBACK_0");
h.setAccessible(true);
Object dynamicAdvisedInterceptor = h.get(proxy);
Field advised = dynamicAdvisedInterceptor.getClass().getDeclaredField("advised");
advised.setAccessible(true);
return ((AdvisedSupport)advised.get(dynamicAdvisedInterceptor)).getTargetSource().getTarget();
}
private static Object getJdkDynamicProxyTargetObject(Object proxy) throws Exception {
Field h = proxy.getClass().getSuperclass().getDeclaredField("h");
h.setAccessible(true);
AopProxy aopProxy = (AopProxy) h.get(proxy);
Field advised = aopProxy.getClass().getDeclaredField("advised");
advised.setAccessible(true);
return ((AdvisedSupport)advised.get(aopProxy)).getTargetSource().getTarget();
}
}
具體使用
//先對Service進行Mock,使用註解的時候需要進行init,這裏不做介紹
@Mock
XxService xxService
//或者
XxService xxService = Mockito.mock(XxService);
//以上是創建XxService的mock
//然後同樣通過when...thenReturn 對XxService的某方法的返回值進行Mock
Mockito.when(xxService.get()).thenReturn(true);
//最後通過工具類進行Service的替換 ReflectionTestUtils.setField(AopTargetUtils.getTarget(aManager),"xxService",xxServiceMock);
具體的原理和詳細mock的內容後續再進行補充,這篇博文主要是對今天碰到的抽象類的方法的測試進行總結