PowerMock入门
PowerMock的maven依赖
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>2.0.0-beta.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.23.4</version>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>2.0.0-beta.5</version>
<scope>test</scope>
</dependency>
PowerMock有两个重要的注解:
//指定执行方法
@RunWith(PowerMockRunner.class)
//指定需要被mock的静态类
@PrepareForTest( { YourClassWithEgStaticMethod.class })
如果你的测试用例里没有使用注解@PrepareForTest,那么可以不用加注解@RunWith(PowerMockRunner.class),反之亦然。
当需要使用PowerMock强大功能(Mock静态、final、私有方法等)的时候,就需要加注解@PrepareForTest。
mock方法
//mock静态类
PowerMockito.mockStatic(LoginUtil.class);
//mock带返回值的方法
PowerMockito.when(LoginUtil.getUser()).thenReturn(new LoginUser());
//mock没有返回值(void)的方法
doNothing().when(bookService).deleteBookById(Mockito.any(),Mockito.any());
//mock调用方法抛出异常
doThrow(new RuntimeException()).when(bookService).addBook(Mockito.any(),Mockito.any());
PowerMock基本用法
1.普通Mock: Mock参数传递的对象
测试目标代码:
public class FlySunDemo {
public boolean callArgumentInstance(File file) {
return file.exists();
}
}
测试代码:
@RunWith(PowerMockRunner.class)
public class FlySunMockTest {
@Test
public void testCallArgumentInstance(){
//mock出入参File对象
File file = PowerMockito.mock(File.class);
FlySunDemo demo = new FlySunDemo();
PowerMockito.when(file.exists()).thenReturn(true);
Assert.assertTrue(demo.callArgumentInstance(file));
}
}
说明:普通Mock不需要加@RunWith和@PrepareForTest注解。
2.Mock方法内部new出来的对象
测试目标代码:
public class FlySunDemo {
public boolean callArgumentInstance(String path) {
File file = new File(path);
return file.exists();
}
}
测试代码:
@RunWith(PowerMockRunner.class)
public class FlySunMockTest {
@Test
@PrepareForTest(FlySunDemo.class)
public void testCallArgumentInstance(){
File file = PowerMockito.mock(File.class);
try {
PowerMockito.whenNew(File.class).withArguments("bbb").thenReturn(file);
FlySunDemo demo = new FlySunDemo();
PowerMockito.when(file.exists()).thenReturn(true);
Assert.assertTrue(demo.callArgumentInstance("bbb"));
} catch (Exception e) {
e.printStackTrace();
}
}
}
说明:当使用PowerMockito.whenNew方法时,必须加注解@PrepareForTest和@RunWith。注解@PrepareForTest里写的类是需要mock的new对象代码所在的类。
3.Mock普通对象的final方法
测试目标代码:
public class ClassDependency {
public final boolean isAlive() {
// do something
return false;
}
}
public class FlySunDemo {
public boolean callFinalMethod(ClassDependency refer) {
return refer.isAlive();
}
}
测试代码:
@RunWith(PowerMockRunner.class)
public class FlySunMockTest {
@Test
@PrepareForTest(ClassDependency.class)
public void testCallFinalMethod() {
ClassDependency refer = PowerMockito.mock(ClassDependency.class);
PowerMockito.when(refer.isAlive()).thenReturn(true);
FlySunDemo demo = new FlySunDemo();
Assert.assertTrue(demo.callFinalMethod(refer));
}
}
说明: 当需要mock final方法的时候,必须加注解@PrepareForTest和@RunWith。注解@PrepareForTest里写的类是final方法所在的类。
4.Mock普通类的静态方法
测试目标代码:
public class ClassDependency {
public static boolean isAlive() {
// do something
return false;
}
}
public class FlySunDemo {
public boolean callStaticMethod() {
return ClassDependency.isAlive();
}
}
测试代码:
@RunWith(PowerMockRunner.class)
public class FlySunMockTest {
@Test
@PrepareForTest(ClassDependency.class)
public void testCallFinalMethod() {
PowerMockito.mockStatic(ClassDependency.class);
PowerMockito.when(ClassDependency.isAlive()).thenReturn(true);
FlySunDemo demo = new FlySunDemo();
Assert.assertTrue(demo.callStaticMethod());
}
}
说明:当需要mock静态方法的时候,必须加注解@PrepareForTest和@RunWith。注解@PrepareForTest里写的类是静态方法所在的类。
5.Mock 私有方法
测试目标代码:
public class FlySunDemo {
public boolean callPrivateMethod() {
return isAlive();
}
private boolean isAlive() {
return false;
}
}
测试代码:
@RunWith(PowerMockRunner.class)
public class FlySunMockTest {
@Test
@PrepareForTest(FlySunDemo.class)
public void testCallFinalMethod() throws Exception {
FlySunDemo demo = PowerMockito.mock(FlySunDemo.class);
PowerMockito.when(demo.callPrivateMethod()).thenCallRealMethod();
PowerMockito.when(demo, "isAlive").thenReturn(true);
Assert.assertTrue(demo.callPrivateMethod());
}
}
说明:注解里写的类是私有方法所在的类。
6.Mock系统类的静态和final方法
测试目标代码:
public class FlySunDemo {
public String callSystemStaticMethod(String str) {
return System.getProperty(str);
}
}
测试代码:
@RunWith(PowerMockRunner.class)
public class FlySunMockTest {
@Test
@PrepareForTest(FlySunDemo.class)
public void testCallSystemStaticMethod(){
FlySunDemo demo = new FlySunDemo();
PowerMockito.mockStatic(System.class);
PowerMockito.when(System.getProperty("aaa")).thenReturn("bbb");
Assert.assertEquals("bbb", demo.callSystemStaticMethod("aaa"));
}
}
说明:和Mock普通对象的静态方法、final方法一样
7.Mock系统类的没有返回值的静态方法
测试目标代码:
mport vip.fkandy.powermock.common.Employee;
/**
* @author
*/
public class EmployeeDao {
/**
* 查询员工数
* @return
*/
public static int getEmployeeCount() {
throw new UnsupportedOperationException();
}
/**
* 添加员工
* @param employee
*/
public static void addEmployee(Employee employee) {
throw new UnsupportedOperationException();
}
}
import vip.fkandy.powermock.common.Employee;
/**
* @author
*/
public class EmployeeService {
public int getEmployeeCount() {
return EmployeeDao.getEmployeeCount();
}
public void addEmployee(Employee employee) {
EmployeeDao.addEmployee(employee);
}
}
测试代码:
@RunWith(PowerMockRunner.class)
@PrepareForTest(EmployeeDao.class)
public class EmployeeServiceTest {
/**
* 有返回值的测试用例
*/
@Test
public void getEmployeeCount() {
//Enable static mocking for all methods of a class
PowerMockito.mockStatic(EmployeeDao.class);
PowerMockito.when(EmployeeDao.getEmployeeCount()).thenReturn(10);
EmployeeService employeeService = new EmployeeService();
int result = employeeService.getEmployeeCount();
assertEquals(10, result);
}
/**
* 无返回值的测试用例
*/
@Test
public void addEmployee() {
PowerMockito.mockStatic(EmployeeDao.class);
//Use doNothing() for setting void methods to do nothing
//
PowerMockito.doNothing().when(EmployeeDao.class);
EmployeeService employeeService = new EmployeeService();
employeeService.addEmployee(new Employee("Andy", 28));
//Verifies certain behavior of the mockedClass happened once,
// Alias to verifyStatic(classMock, times(1))
PowerMockito.verifyStatic(EmployeeDao.class);
}
}