<!--单元测试-->
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.6.5</version>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.6.5</version>
</dependency>
1.全局变量
业务代码
@Component
public class UserService {
@Autowired
private UserDao userDao;
public int queryUserCount(){
return userDao.queryCount();
}
public void saveUser(User user){
userDao.insert(user);
}
}
@Component
public class UserDao {
public int queryCount(){
throw new UnsupportedOperationException();
}
public void insert(User user){
throw new UnsupportedOperationException();
}
}
public class User {
}
单元测试
@RunWith(PowerMockRunner.class)
public class UserServiceTest {
@InjectMocks
private UserService userService;
@Mock
private UserDao userDao;
@Test
public void queryUserCount() {
Mockito.when(userDao.queryCount()).thenReturn(1);
int result = userService.queryUserCount();
assertTrue(result == 1);
}
@Test
public void saveUser() {
User user = new User();
PowerMockito.doNothing().when(userDao).insert(new User());
//注意这里的入参,需要和下面的Mockito.verify(userDao,Mockito.times(1)).insert(user)入参一样
userService.saveUser(user);
Mockito.verify(userDao,Mockito.times(1)).insert(user);
}
}
2.局部变量
业务代码
public class UserService {
public int queryCount(){
UserDao userDao = new UserDao();
return userDao.queryCount();
}
public void save(User user){
UserDao userDao = new UserDao();
userDao.insert(user);
}
}
public class UserDao {
public int queryCount(){
throw new UnsupportedOperationException();
}
public void insert(User user){
throw new UnsupportedOperationException();
}
}
public class User {
}
单元测试
@RunWith(PowerMockRunner.class)
@PrepareForTest({UserService.class})
public class UserServiceTest {
@Test
public void queryCount() throws Exception {
// mock 一个局部new对象
UserDao userDao = PowerMockito.mock(UserDao.class);
// 当代码使用new创建一个对象时,切是没有参数的,则返回这个userDao
PowerMockito.whenNew(UserDao.class).withNoArguments().thenReturn(userDao);
// 当代码中遇到调用userDao.queryCount()方法的时候,直接返回一个1,不糊调
PowerMockito.when(userDao.queryCount()).thenReturn(1);
UserService userService = new UserService();
int i = userService.queryCount();
assertTrue(1==i);
}
@Test
public void save() throws Exception {
User user = new User();
// mock 一个局部new对象
UserDao userDao = PowerMockito.mock(UserDao.class);
// 当代码使用new创建一个对象时,切是没有参数的,则返回这个userDao
PowerMockito.whenNew(UserDao.class).withNoArguments().thenReturn(userDao);
// 因为这里没有返回值,所以行的作用是,当调用userDao.insert(user)时,什么都不做
PowerMockito.doNothing().when(userDao).insert(user);
UserService userService = new UserService();
userService.save(user);
}
}
3. 静态变量
1.如果静态变量是new来的,处理方式和局部变量的一样
业务代码
public class UserService {
private static UserDao userDao = new UserDao();
public int queryCount() {
return userDao.queryCount();
}
public void save(User user) {
userDao.insert(user);
}
}
public class UserDao {
public int queryCount() {
throw new UnsupportedOperationException();
}
public void insert(User user) {
throw new UnsupportedOperationException();
}
}
public class User {
}
单元测试
@RunWith(PowerMockRunner.class)
@PrepareForTest({UserService.class})
public class UserServiceTest {
@Test
public void queryCount() throws Exception {
// mock一个虚拟的UserDao
UserDao userDao = PowerMockito.mock(UserDao.class);
// 当代码使用new创建一个对象时,切是没有参数的,则返回这个userDao,这里和局部变量的一样
PowerMockito.whenNew(UserDao.class).withNoArguments().thenReturn(userDao);
Mockito.when(userDao.queryCount()).thenReturn(1);
UserService userService = new UserService();
int result = userService.queryCount();
assertTrue(result == 1);
}
@Test
public void save() throws Exception {
// mock一个虚拟的UserDao
UserDao userDao = PowerMockito.mock(UserDao.class);
// 当代码使用new创建一个对象时,切是没有参数的,则返回这个userDao,这里和局部变量的一样
PowerMockito.whenNew(UserDao.class).withNoArguments().thenReturn(userDao);
Mockito.when(userDao.queryCount()).thenReturn(1);
UserService userService = new UserService();
User user = new User();
PowerMockito.doNothing().when(userDao).insert(user);
userService.save(user);
}
}
2.静态变量是调用静态方法创建的
业务代码
public class UserService {
private static UserDao userDao = UserDaoUtil.getUserDao();
public int queryCount() {
return userDao.queryCount();
}
public void save(User user) {
userDao.insert(user);
}
}
public class UserDaoUtil {
public static UserDao getUserDao(){
return null;
}
}
public class UserDao {
public int queryCount() {
throw new UnsupportedOperationException();
}
public void insert(User user) {
throw new UnsupportedOperationException();
}
}
public class User {
}
单元测试
@RunWith(PowerMockRunner.class)
// 这里需要填我们需要mock的类,所谓需要被mock的,就是需要被改写字节码的文件,
// 例如这里我们想要改写UserDaoUtil,因为我们在调用这个类的方法时,需要返回一个我们自己的变量
@PrepareForTest({UserDaoUtil.class})
public class UserServiceTest {
@Test
public void queryCount() {
// mock出一个虚拟值
UserDao userDaoMock = PowerMockito.mock(UserDao.class);
// mock这个静态类
PowerMockito.mockStatic(UserDaoUtil.class);
// 当调用这个静态方法时,返回我们mock出来的userDaoMock
PowerMockito.when(UserDaoUtil.getUserDao()).thenReturn(userDaoMock);
Mockito.when(userDaoMock.queryCount()).thenReturn(10);
UserService userService = new UserService();
int result = userService.queryCount();
assertTrue(result == 10);
}
@Test
public void save() {
// mock出一个虚拟值
UserDao userDaoMock = PowerMockito.mock(UserDao.class);
// mock这个静态类
PowerMockito.mockStatic(UserDaoUtil.class);
// 当调用这个静态方法时,返回我们mock出来的userDaoMock
PowerMockito.when(UserDaoUtil.getUserDao()).thenReturn(userDaoMock);
PowerMockito.doNothing().when(userDaoMock).insert(new User());
UserService userService = new UserService();
userService.save(new User());
}
}
4.静态方法mock
业务代码
@Component
public class UserService {
public int queryUserCount() {
return UserDao.getCount();
}
public void saveUser(User user) {
UserDao.save(user);
}
}
public class UserDao {
public static int getCount() {
throw new UnsupportedOperationException();
}
public static void save(User user) {
throw new UnsupportedOperationException();
}
}
public class User {
}
单元测试
@RunWith(PowerMockRunner.class)
@PrepareForTest({UserDao.class})
public class UserServiceTest {
@InjectMocks
private UserService userService;
@Test
public void queryUserCount() {
PowerMockito.mockStatic(UserDao.class);
PowerMockito.when(UserDao.getCount()).thenReturn(10);
int i = userService.queryUserCount();
Assert.assertTrue(i == 10);
}
@Test
public void saveUser() {
PowerMockito.mockStatic(UserDao.class);
PowerMockito.doNothing().when(UserDao.class);
userService.saveUser(new User());
PowerMockito.verifyStatic();
}
}
5.mock静态代码块,以及给静态属性赋值
业务代码
@Component
public class UserService {
private static UserDao userDao;
static {
userDao = new UserDao();
System.out.println("execute static");
}
public int queryUserCount() {
return userDao.getCount();
}
public void saveUser(User user) {
userDao.save(user);
}
}
public class UserDao {
public int getCount() {
throw new UnsupportedOperationException();
}
public void save(User user) {
throw new UnsupportedOperationException();
}
}
public class User {
}
单元测试
@RunWith(PowerMockRunner.class)
// 这个注解是代表我们需要跳过哪个类的静态代码块,值为类的全路径
@SuppressStaticInitializationFor("com.basci.powermock.mockstatic.block.UserService")
public class UserServiceTest {
@InjectMocks
private UserService userService;
@Test
public void queryUserCount() throws IllegalAccessException {
// 创建我们模拟的对象
UserDao userDao = mock(UserDao.class);
// 获取我们需要赋值的对象
Field field = PowerMockito.field(UserService.class, "userDao");
// 设置值
field.set(UserService.class, userDao);
// 当调用userDao.getCount()方法时返回10
PowerMockito.when(userDao.getCount()).thenReturn(10);
int result = userService.queryUserCount();
Assert.assertTrue(result == 10);
}
@Test
public void saveUser() throws IllegalAccessException {
// 创建我们模拟的对象
UserDao userDao = mock(UserDao.class);
// 获取我们需要赋值的对象
Field field = PowerMockito.field(UserService.class, "userDao");
// 设置值
field.set(UserService.class, userDao);
// 当调用userDao.getCount()方法时返回10
User user = new User();
PowerMockito.doNothing().when(userDao).save(user);
userService.saveUser(user);
Mockito.verify(userDao,Mockito.times(1)).save(user);
}
}
6.mock 私有方法
@Component
public class UserService {
@Autowired
private UserDao userDao;
private int queryUserCount(){
return userDao.queryCount();
}
private void saveUser(User user){
userDao.insert(user);
}
}
@Component
public class UserDao {
public int queryCount(){
throw new UnsupportedOperationException();
}
public void insert(User user){
throw new UnsupportedOperationException();
}
}
public class User {
}
单元测试
@RunWith(PowerMockRunner.class)
public class UserServiceTest {
@InjectMocks
private UserService userService;
@Mock
private UserDao userDao;
@Test
public void queryUserCount() throws InvocationTargetException, IllegalAccessException {
PowerMockito.when(userDao.queryCount()).thenReturn(10);
Method method = PowerMockito.method(UserService.class, "queryUserCount");
int result = (int) method.invoke(userService);
Assert.assertTrue(result == 10);
}
@Test
public void save() throws InvocationTargetException, IllegalAccessException {
User user = new User();
PowerMockito.when(userDao.queryCount()).thenReturn(10);
Method method = PowerMockito.method(UserService.class, "saveUser", User.class);
method.invoke(userService,user);
Mockito.verify(userDao,Mockito.times(1)).insert(user);
}
}
7.mock异常
业务代码
@Component
public class UserService {
@Autowired
private UserDao userDao;
public int queryUserCount(){
return userDao.queryCount();
}
public void saveUser(User user){
userDao.insert(user);
}
}
@Component
public class UserDao {
public int queryCount(){
throw new UnsupportedOperationException();
}
public void insert(User user){
throw new UnsupportedOperationException();
}
}
public class User {
}
单元测试
@RunWith(PowerMockRunner.class)
public class UserServiceTest {
@InjectMocks
private UserService userService;
@Mock
private UserDao userDao;
@Test
public void queryUserCount() {
try {
PowerMockito.when(userDao.queryCount()).thenThrow(new RuntimeException("1234"));
userService.queryUserCount();
fail("不能执行到这行代码");
}catch (Exception e){
Assert.assertTrue(e instanceof RuntimeException);
}
}
@Test
public void saveUser() {
try {
User user = new User();
PowerMockito.doThrow(new ReadPendingException()).when(userDao).insert(user);
userService.saveUser(user);
fail("不能执行到这行代码");
}catch (Exception e){
Assert.assertTrue(e instanceof ReadPendingException);
}
}
}
8.mock同一个类中的方法调用
业务代码
@Component
public class UserService {
@Autowired
private UserDao userDao;
public int queryUserCount(String name){
return getCount(name);
}
private int getCount(String name) {
throw new UnsupportedOperationException();
}
public void saveUser(User user){
save(user);
}
private void save(User user) {
throw new UnsupportedOperationException();
}
}
@Component
public class UserDao {
public int queryCount(){
throw new UnsupportedOperationException();
}
public void insert(User user){
throw new UnsupportedOperationException();
}
}
public class User {
}
单元测试
@RunWith(PowerMockRunner.class)
@PrepareForTest(UserService.class)
public class UserServiceTest {
@InjectMocks
private UserService userService;
@Test
public void queryUserCount() throws Exception {
UserService spy = PowerMockito.spy(userService);
PowerMockito.doReturn(1).when(spy,"getCount","nametest");
// 如果参数与上面mock的一样,则不会调用,参数不一样,则会调用
spy.queryUserCount("nametest");
}
@Test
public void saveUser() throws Exception {
User user = new User();
UserService spy = PowerMockito.spy(userService);
PowerMockito.doNothing().when(spy,"save",user);
spy.saveUser(user);
}
}