import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
@RunWith(PowerMockRunner.class)
@PrepareForTest({ MyClass.class})
public class StaticClassSampleTest {
@Test
public void testPrivateMethod() throws Exception {
// 模拟 private的方法
MyClass spy = PowerMockito.spy(new MyClass());
PowerMockito.doReturn(3).when(spy, "private_method", 1);
Assert.assertEquals(3, spy.test_private_method(1));
PowerMockito.verifyPrivate(spy, Mockito.times(1)).invoke("private_method", 1);
}
@Test
public void testStaticReturnMethod() throws Exception {
// 模拟 静态有返回值的方法
PowerMockito.mockStatic(MyClass.class);
Mockito.when(MyClass.static_return_method()).thenReturn(2);
Assert.assertEquals(2, MyClass.static_return_method());
}
@Test
public void testVoidMethod() throws Exception {
// 模拟 不执行void的方法
MyClass spy = PowerMockito.spy(new MyClass());
PowerMockito.doNothing().when(spy).void_method();
spy.void_method();
}
@Test
public void testStaticMethod1() throws Exception {
// 模拟 不执行没参数的静态void的方法
PowerMockito.mockStatic(MyClass.class);
PowerMockito.doNothing().when(MyClass.class, "static_void_method");
MyClass.static_void_method();
}
@Test
public void testStaticMethod2() throws Exception {
// 模拟 不执行带参数的静态void的方法
PowerMockito.mockStatic(MyClass.class);
PowerMockito.doNothing().when(MyClass.class, "staticMethod", "123");
MyClass.staticMethod("123");
PowerMockito.doNothing().when(MyClass.class, "staticMethod", Mockito.anyString());
MyClass.staticMethod("456");
}
}
class MyClass {
final private int private_method(int a) {
return a;
}
public int test_private_method(int a) {
return private_method(a);
}
public static int static_return_method() {
return 1;
}
void void_method() {
throw new IllegalStateException("should not go here");
}
public static void static_void_method() {
throw new IllegalStateException("should not go here");
}
public static void staticMethod(String a) {
throw new IllegalStateException(a);
}
}
maven依赖
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.8.5</version>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.4.10</version>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.4.10</version>
</dependency>
另外补一下,测试目标方法内部对象的mock方式:
// 测试目标代码:
public class ClassUnderTest {
public boolean callInternalInstance(String path) {
File file = new File(path);
return file.exists();
}
}
// 测试用例代码
@RunWith(PowerMockRunner.class)
public class TestClassUnderTest{
@Test
@PrepareForTest(ClassUnderTest.class)
public void testCallInternalInstance() throws Exception{
File file = PowerMockito.mock(File.class);
ClassUnderTest underTest = new ClassUnderTest();
PowerMockito.whenNew(File.class).withArguments("bbb").thenReturn(file);
PowerMockito.when(file.exists()).thenReturn(true);
Assert.assertTrue(underTest.callInternalInstance("bbb"));
}
}
*当某个测试方法被注解@PrepareForTest标注以后,
在运行测试用例时,会创建一个新的org.powermock.
core.classloader.MockClassLoader实例,
然后加载该测试用例使用到的类(系统类除外)。
*PowerMock会根据你的mock要求,去修改写在
注解@PrepareForTest里的class文件(当前测
试类会自动加入注解中),以满足特殊的mock需求。
例如:去除final方法的final标识,
在静态方法的最前面加入自己的虚拟实现等。
*如果需要mock的是系统类的final方法和静态方法,
PowerMock不会直接修改系统类的class文件,
而是修改调用系统类的class文件,以满足mock需求。