背景
由于Mockito的局限性,對final、private、static等方法不能mock,PowerMockito測試框架正好彌補(bǔ)Mockito的不足。
PowerMockito入門
依賴配置
// PowerMock
testCompile 'org.powermock:powermock-module-junit4:1.6.5'
testCompile 'org.powermock:powermock-module-junit4-rule:1.6.5'
testCompile 'org.powermock:powermock-api-mockito:1.6.5'
testCompile 'org.powermock:powermock-classloading-xstream:1.6.5'
PowerMock有三個重要的注解:
@RunWith(PowerMockRunner.class)
@PrepareForTest({YourClassWithEgStaticMethod.class})
@PowerMockIgnore("javax.management.*")
如果你的測試用例里沒有使用注解@PrepareForTest,那么可以不用加注解@RunWith(PowerMockRunner.class),反之亦然。當(dāng)你需要使用PowerMock強(qiáng)大功能(Mock靜態(tài)、final、私有方法等)的時候,就需要加注解@PrepareForTest。這一點(diǎn)和Mockito的使用方式是類似的,要么使用這種注解的方式
@RunWith(PowerMockRunner.class)
@PrepareForTest({YourClassWithEgStaticMethod.class})
PowerMockito使用
public class ClassUnder {
public boolean callArgumentInstance(File file) {
return file.exists();
}
public boolean callInternalInstance(String path) {
File file = new File(path);
return file.exists();
}
public boolean callFinalMethod(ClassDependency refer) {
return refer.isAlive();
}
public boolean callStaticMethod() {
return ClassDependency.isExist();
}
public boolean callPrivateMethod() {
return isExist();
}
public String callSystemStaticMethod(String str) {
return System.getProperty(str);
}
private boolean isExist() {
return false;
}
}
public class ClassDependency {
public final boolean isAlive() {
// do something
return false;
}
public static boolean isExist() {
// do something
return false;
}
}
測試代碼的類體:
public class ClassUnderTest {
private ClassUnder classUnder;
@Before
public void setUp() throws Exception {
classUnder = new ClassUnder();
}
}
普通Mock: Mock參數(shù)傳遞的對象
測試目標(biāo)方法:callArgumentInstance
測試用例代碼:
@Test
public void testCallArgumentInstance() throws Exception {
File file = PowerMockito.mock(File.class);
PowerMockito.when(file.exists()).thenReturn(true);
assertTrue(classUnder.callArgumentInstance(file));
}
說明:普通Mock不需要加@RunWith和@PrepareForTest注解。
Mock方法內(nèi)部new出來的對象
測試目標(biāo)方法:callInternalInstance
測試用例代碼:
@Test
@PrepareForTest(ClassUnder.class)
public void testCallInternalInstance() throws Exception {
File file = PowerMockito.mock(File.class);
//當(dāng)內(nèi)部new一個對象,并且傳入的參數(shù)是"test",就返回一個File對象。
PowerMockito.whenNew(File.class).withArguments("test").thenReturn(file);
PowerMockito.when(file.exists()).thenReturn(true);
assertTrue(classUnder.callInternalInstance("test"));
}
- 當(dāng)使用PowerMockito.whenNew方法時,必須加注解@PrepareForTest和@RunWith。
- 注解@PrepareForTest里寫的類是需要mock的new對象代碼所在的類。
Mock普通對象的final方法
測試目標(biāo)方法:callFinalMethod
測試用例代碼:
@Test
@PrepareForTest(ClassDependency.class)
public void callFinalMethod() throws Exception {
ClassDependency classDependency = PowerMockito.mock(ClassDependency.class);
PowerMockito.when(classDependency.isAlive()).thenReturn(true);
assertTrue(classUnder.callFinalMethod(classDependency));
}
- 當(dāng)需要mock final方法的時候,必須加注解@PrepareForTest和@RunWith。
- 注解@PrepareForTest里寫的類是final方法所在的類。
Mock普通類的靜態(tài)方法
測試目標(biāo)方法:callStaticMethod
測試用例代碼:
@Test
@PrepareForTest(ClassDependency.class)
public void callStaticMethod() throws Exception {
//mock靜態(tài)方法所在的類
PowerMockito.mockStatic(ClassDependency.class);
PowerMockito.when(ClassDependency.isExist()).thenReturn(true);
assertTrue(classUnder.callStaticMethod());
}
- 當(dāng)需要mock靜態(tài)方法的時候,必須加注解@PrepareForTest和@RunWith
- 注解@PrepareForTest里寫的類是靜態(tài)方法所在的類。
Mock私有方法
測試目標(biāo)方法:callPrivateMethod
測試用例代碼:
@Test
@PrepareForTest(ClassUnder.class)
public void callPrivateMethod() throws Exception {
//mock 私有方法的類 ClassUnder
ClassUnder under = PowerMockito.mock(ClassUnder.class);
//當(dāng)執(zhí)行classUnder.callPrivateMethod()的時候調(diào)用它實(shí)際的方法。
PowerMockito.when(under.callPrivateMethod()).thenCallRealMethod();
PowerMockito.when(under,"isExist").thenReturn(true);
assertTrue(under.callPrivateMethod());
}
- 和Mock普通方法一樣,只是需要加注解@PrepareForTest(ClassUnderTest.class)
- 注解里寫的類是私有方法所在的類。
Mock系統(tǒng)類的靜態(tài)和final方法
測試目標(biāo)方法:callSystemStaticMethod
測試用例代碼:
@Test
@PrepareForTest(ClassUnder.class)
public void callSystemStaticMethod() throws Exception {
PowerMockito.mockStatic(System.class);
PowerMockito.when(System.getProperty("aaa")).thenReturn("bbb");
assertEquals("bbb",classUnder.callSystemStaticMethod("aaa"));
}
- 說明:和Mock普通對象的靜態(tài)方法、final方法一樣,只不過注解@PrepareForTest里寫的類不一樣
- 注解里寫的類是需要調(diào)用系統(tǒng)方法所在的類