PowerMock使用记录

<!--单元测试-->
        <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);
    }
}
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值