PowerMockito使用详解

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);
    }
}
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值