前言
Verifying是一个非常强大的测试工具,在mock系列框架中使用广泛,主要用于验证方法是否被调用,下面将举例说明。
场景
模拟这样一个场景,通过Dao查询学生,如果存在更新原来学生,不存在则创建一个学生。
1、先来创建dao层的代码,具体示例代码如下:
package com.rongrong.powermock.verifying;
/**
* @author rongrong
* @version 1.0
* @date 2019/11/26 20:56
*/
public class StudentVerifyDao {
public int getStudentCount(Student student) {
throw new UnsupportedOperationException();
}
public void saveStudent(Student student) {
throw new UnsupportedOperationException();
}
public void updateStudent(Student student) {
throw new UnsupportedOperationException();
}
}
2、接着我们再来编写,service层的代码,具体示例代码如下:
package com.rongrong.powermock.verifying;
import org.junit.Test;
/**
* @author rongrong
* @version 1.0
* @date 2019/11/26 21:05
*/
public class StudentVerifyService {
public void saveOrUpdate(Student student) {
final StudentVerifyDao verifyDao = new StudentVerifyDao();
int count = verifyDao.getStudentCount(student);
if (count > 0) {
verifyDao.updateStudent(student);
} else {
verifyDao.saveStudent(student);
}
}
@Test
public void test(){
StudentVerifyService verifyService = new StudentVerifyService();
verifyService.saveOrUpdate(new Student());
}
}
3、接着来做个简单的单元测试,也可以说是调用吧,这段代码运行是必须报错的,这里就不做解释,为什么报错了,代码如下:
@Test
public void test(){
StudentVerifyService verifyService = new StudentVerifyService();
verifyService.saveOrUpdate(new Student());
}
直接运行,报错如下图所示:

4、使用powermock来测试,具体代码如下:
package com.rongrong.powermock.verifying;
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;
/**
* @author rongrong
* @version 1.0
* @date 2019/11/26 22:05
*/
@RunWith(PowerMockRunner.class)
//提前将StudentVerifyService这个类准备好
@PrepareForTest(StudentVerifyService.class)
public class TestStudentVerifyService {
@Test
public void testStudentLessThanZero(){
//mock一个假对象
StudentVerifyDao studentVerifyDao = PowerMockito.mock(StudentVerifyDao.class);
//mock对象构造过程
try {
PowerMockito.whenNew(StudentVerifyDao.class).withNoArguments().thenReturn(studentVerifyDao);
Student student = new Student();
//模拟当调用查询学生个数时候,没有找到,我给了0
PowerMockito.when(studentVerifyDao.getStudentCount(student)).thenReturn(0);
StudentVerifyService studentVerifyService = new StudentVerifyService();
//调用保存并更新方法
studentVerifyService.saveOrUpdate(student);
//没有那么走的就是保存方法啦
Mockito.verify(studentVerifyDao).saveStudent(student);
//这里就不走更新了,所以用了mockito.never()方法
Mockito.verify(studentVerifyDao,Mockito.never()).updateStudent(student);
} catch (Exception e) {
e.printStackTrace();
}
}
@Test
public void testStudentMoreThanZero(){
//mock一个假对象
StudentVerifyDao studentVerifyDao = PowerMockito.mock(StudentVerifyDao.class);
Student student = new Student();
try {
//mock对象构造过程即局部变量构造
PowerMockito.whenNew(StudentVerifyDao.class).withNoArguments().thenReturn(studentVerifyDao);
//模拟调用查询学生存在,那么返回值给1即可
PowerMockito.when(studentVerifyDao.getStudentCount(student)).thenReturn(1);
StudentVerifyService studentVerifyService = new StudentVerifyService();
//调用保存并更新方法
studentVerifyService.saveOrUpdate(student);
//如果存在,这里要去更新学生信息
Mockito.verify(studentVerifyDao).updateStudent(student);
//Mockito.never()后就不会走保存的方法了
Mockito.verify(studentVerifyDao,Mockito.never()).saveStudent(student);
} catch (Exception e) {
e.printStackTrace();
}
}
}
直接运行,你会发现,运行通过,如下图所示:

总结
1、仔细看,在service中有个局部变量,这也就注定了我们只能使用powermock来测试
2、当有Mockito.never()出现的时候当前修饰行的方法将不被执行
3、这块应用的事mock局部变量的方法的使用,只是加了些方法后,变得复杂看似,但实际并不复杂,还请感兴趣的朋友,反复实践。