前言
本計划在上周六日將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)。