PowerMock学习之Mock Argument Matcher的使用

Posted longronglang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PowerMock学习之Mock Argument Matcher的使用相关的知识,希望对你有一定的参考价值。

前言

本计划在上周六日将powermock学完,并同步到博客中,结果自己没经得住诱惑,又开始去打王者荣耀了。虽然两天时间我从钻石一升到了星耀V四星,不得不说腾讯的游戏做的用户粘度真高,厉害的狠。

言归正传,周一上班后开始收拾心情,接着我每天的学习之路,本应该昨天更新文章的有一处代码一直报错未解决,卡了很久,直到今天才解决,就像丝瓜妹说的,学习其实一直是闭门造车。。。我太难了。。。。。

关于Argument Matcher

从英文字面理解,就是说的是参数匹配相关的事,也就是在mock中,这块主要是为了处理方法间调用传入的不同参数,返回不同内容使用的。

模拟场景

很简单,模拟输入用户名查找电话号码,即使用controller调用service服务

代码实现

service部分

具体示例代码如下:

package com.rongrong.powermock.matcher;

/**
 * @author rongrong
 * @version 1.0
 * @description:
 * @date 2019/12/3 21:02
 */
public class StundentMatcherService {

    public String getPhoneNum(String userName) {
        throw new UnsupportedOperationException();
    }
}

 

controller部分

具体示例代码如下:

package com.rongrong.powermock.matcher;

/**
 * @description:controller调用service
 * @author rongrong
 * @version 1.0
 * @date 2019/12/3 20:55
 */
public class StudentController {

    public String getPhoneNum(String userName){
        StundentMatcherService stundentMatcherService = new StundentMatcherService();
        return stundentMatcherService.getPhoneNum(userName);
    }
}

 

因为存在局部变量,肯定使用powermock来测试,使用之前学过的办法测试,具体示例代码如下:

package com.rongrong.powermock.matcher;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static junit.framework.TestCase.assertEquals;

/**
 * @description:之前学过的方法测试
 * @author rongrong
 * @version 1.0
 * @date 2019/12/3 21:10
 */
@RunWith(PowerMockRunner.class)
@PrepareForTest(StudentController.class)
public class TestStudentMatcher {

    @Test
    public void testStudentMatcher(){
        StundentMatcherService stundentMatcherService = PowerMockito.mock(StundentMatcherService.class);
        PowerMockito.when(stundentMatcherService.getPhoneNum("xiaoqiang")).thenReturn("15111111111");
        try {
            PowerMockito.whenNew(StundentMatcherService.class).withAnyArguments().thenReturn(stundentMatcherService);
            StudentController studentController = new StudentController();
            String phoneNum = studentController.getPhoneNum("xiaoqiang");
            assertEquals("15111111111",phoneNum);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

细心的同学,可能会发现,我这块只录制了查询用户名xiaoqiang,然后返回一个电话号码,那比如我想查alex,Tom,xiaoming,tony等等这些同学的电话号,是不是都需要加入以下代码:

        PowerMockito.when(stundentMatcherService.getPhoneNum("alex")).thenReturn("15111111111");
        PowerMockito.when(stundentMatcherService.getPhoneNum("Tom")).thenReturn("15111111111");
        PowerMockito.when(stundentMatcherService.getPhoneNum("xiaoming")).thenReturn("15111111111");
        PowerMockito.when(stundentMatcherService.getPhoneNum("tony")).thenReturn("15111111111");

如果没加则返回null,难道我们需要手动去添加,代码上看肯定是冗余的,那么怎么办呢,我们采用mock中的 Argument Matcher来进行测试。

具体代码如下:

package com.rongrong.powermock.matcher;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatcher;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.fail;

/**
 * @author rongrong
 * @version 1.0
 * @description:
 * @date 2019/12/3 21:23
 */
@RunWith(PowerMockRunner.class)
@PrepareForTest(StudentController.class)
public class TestStudentMatcherWithArgMather {

    @Test
    public void testStudentMatcherWithArgMather(){
        StundentMatcherService stundentMatcherService = PowerMockito.mock(StundentMatcherService.class);
        PowerMockito.when(stundentMatcherService.getPhoneNum(Mockito.argThat(new ArgumentMatcher<String>() {
            @Override
            public boolean matches(Object argument) {
                String arg=(String)argument;
                if(arg.startsWith("rr")||arg.contains("rongrong"))
                    return true;
                else
                    return false;
                    //使用运行时异常也可,只是使用后看不到,匹配不到情况返回值效果
                   //throw new RuntimeException();
            }
        }))).thenReturn("010-888888888");
        try {
            PowerMockito.whenNew(StundentMatcherService.class).withAnyArguments().thenReturn(stundentMatcherService);
            StudentController studentController = new StudentController();
            //验证存在的时候,返回匹配结果
            String phoneNum = studentController.getPhoneNum("rr");
            assertEquals("010-888888888",phoneNum);
            //验证不存在的时候,返回null
            phoneNum = studentController.getPhoneNum("jiuqujian");
            assertEquals("010-888888888",phoneNum);
        } catch (Exception e) {
            fail("test fail!!!");
        }

    }
}
 
通过实现一个匿名 ArgumentMatcher 类,实现了根据不同参数获得不同的返回结果预期,这样我们就可以少些很多when...thenReturn书写。

以上是关于PowerMock学习之Mock Argument Matcher的使用的主要内容,如果未能解决你的问题,请参考以下文章

PowerMock学习之Mock局部变量

PowerMock学习之Mock spy的使用

PowerMock学习之Verifying的使用

powermock mock静态方法为啥会执行

如何使用Powermock对静态方法进行mock

powermock, 强力模拟