前言
本计划在上周六日将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() { @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)。