PowerMock是最近主要使用的自动化测试框架,主要有强大的mock能力,无论是静态方法还是接口调用。但是今天遇到一个问题,关于范型返回 mock的问题,最后问题得到了解决,我看中文引擎基本没这个问题的解决方案,所以特此记录以下。
- 首先看我需要 mock 的对象和方法
/**
* User基类
* 两个具体类Manager 与 Programer
*/
abstract class User {
}
class Manager extends User {
}
class Programer extends User {
}
/**
* 需要mock的方法
*/
interface UserService {
/**
* 上界限定范化集合
* @return
*/
List<? extends User> getUserList();
/**
* 上界限定范化集合
* @param <T>
* @return
*/
<T extends User> List<T> getSpecifyUserList();
}
两个方法的区别我想大家应该都会知道有啥区别,不过我还是想解释下:
class UserServiceImpl implements UserService {
@Override
public List<? extends User> getUserList() {
// 这里返回的集合可以是一种或多种User子类
List<User> userList = Lists.newArrayList();
userList.add(new Manager());
userList.add(new Programer());
return userList;
}
@Override
public <T extends User> List<T> getSpecifyUserList() {
// 这里返回的集合必须是一种User子类
List<Programer> userList = Lists.newArrayList();
userList.add(new Programer());
return (List<T>) userList;
}
}
- PowerMock进行mock方法
@Test
public void mock() {
System.out.println("hello MockPowerito!");
}
@Test
public void mockTestGeneric() {
UserService userService = PowerMockito.mock(UserService.class);
// 这里报编译错误,提示不能解析该方法
PowerMockito.when(userService.getUserList()).thenReturn(mockProgramerList());
}
private List<? extends User> mockProgramerList() {
return Lists.newArrayList(new Programer());
}
不能mock因为有类型安全校验。其实mock有绕过类型校验的方法doReturn
UserService userService = PowerMockito.mock(UserService.class);
// PowerMockito.when(userService.getUserList()).thenReturn(mockProgramerList());
// 正确姿势
PowerMockito.doReturn(mockProgramerList()).when(userService).getUserList();
(注意前面的when是方法级别,正确姿势是when类级别)这样即可达到预期mock。