Mock測試框架(Mockito為例)


  在做單元測試的時候,有的時候用到的一些類,我們構造起來不是那么容易,比如HttpRequest,或者說某個Service依賴到了某個Dao,想構造service還得先構造dao,這些外部對象構造起來比較麻煩。 所以出現了Mock! 我們可以用 Mock 工具來模擬這些外部對象,來完成我們的單元測試。

  實現Mock技術的優秀開源框架有很多,下面以Mockito為例,用幾個簡單例子來介紹Mock工具的基本使用:

       1.Mockito的第一個示例

 1 @Test  
 2     public void simpleTest(){  
 3           
 4         //創建mock對象,參數可以是類,也可以是接口  
 5         List<String> list = Mockito.mock(List.class);  
 6           
 7         //設置方法的預期返回值 (如果list.get(0) 被調用 ,調用之后返回 helloworld)
 8         //當然前提是要創建了Mock對象,如這里就是創建了跟 List相關的 Mock對象
 9         //這里還看不出什么作用,因為Mock 還看不出來,List很容易就能創建
10         //假如是一個很復雜的對象,構造這樣一個對象很有難度,使用Mock就很方便了,我們不用去一步一步填充它的屬性去構造,
11         //只需要Mock 一下,就可以拿到這個對象,去測試它的方法,(當然,如果方法有參數我們是需要傳遞的,像get(0))
12         Mockito.when(list.get(0)).thenReturn("helloworld");  
13         //list.get(0)的調用就會返回 helloworld
14         String result = list.get(0);  
15         System.out.println(result);
16         
17         //驗證方法調用(是否調用了get(0))  
18         Mockito.verify(list).get(0); 
19         
20         Assert.assertEquals("helloworld", result); 
21     }  
 1 @Test
 2 public void testMockMethod() {
 3     Class1Mocked obj=mock(Class1Mocked.class);①
 4 
 5     when(obj.hello("z3")).thenReturn("hello l4");②
 6 
 7     String actual=obj.hello("z3");③
 8     assertEquals("hello l4",actual);
 9     
10     verify(obj).hello("z3");④
11     //verify(obj,times(1)).hello("z3"); //可以加參數驗證次數
12 }

  2.驗證順序

 1  @Test
 2     public void testMockMethodInOrder() {
 3         Class1Mocked objOther = Mockito.mock(Class1Mocked.class);
 4         Class1Mocked objCn = Mockito.mock(Class1Mocked.class);
 5 
 6         Mockito.when(objOther.hello("z3")).thenReturn("hello l4");
 7         Mockito.when(objCn.hello("z3")).thenReturn("hello 張三");
 8 
 9         String other = objOther.hello("z3");  //這里決定了 objOther在先
10         Assert.assertEquals("hello l4", other);
11         String cn = objCn.hello("z3");          //這里決定了 objCn在后
12         Assert.assertEquals("hello 張三", cn);
13 
14         InOrder inOrder = Mockito.inOrder(objOther, objCn); //此行並不決定順序,下面的兩行才開始驗證順序
15         inOrder.verify(objOther).hello("z3");
16         inOrder.verify(objCn).hello("z3");
17     }

 

  3.非局部模擬

 1 // 非局部模擬(只能通過When().thenReturn() 來指定函數的返回類型,但是是調用不了 模擬出來的的類的方法的)
 2     @Test
 3     public void testSkipExpect() {
 4         Class1Mocked obj = Mockito.mock(Class1Mocked.class);
 5         
 6         //如:正常如果hello方法被調用,應該返回z3,但這里返回的null ,說明該方法是沒有被調用的
 7         //因為我們模擬出來的是非局部變量
 8         Assert.assertEquals(null, obj.hello("z3"));
 9         //show方法也是一樣,show方法如果執行應該打印一句話,但是obj並不能執行show方法
10         obj.show();
11 
12         Mockito.verify(obj).hello("z3");
13         Mockito.verify(obj).show();
14     }

 

  4.局部模擬

 1 //局部模擬--spy()方式
 2     @Test
 3     public void testSpy() {
 4         Class1Mocked obj = Mockito.spy(new Class1Mocked());
 5         
 6         Mockito.doNothing().when(obj).show();  //有了這行,show方法被執行就不會有任何操作
 7         
 8         Assert.assertEquals("z3",obj.hello("z3"));
 9         obj.show();
10         
11         Mockito.verify(obj).hello("z3");
12         Mockito.verify(obj).show();
13     }

 

  5.陷阱

 1 //值得注意的陷阱
 2     @Test
 3     public void testSpy2() {
 4         Class1Mocked obj = Mockito.spy(new Class1Mocked());
 5         //即使使用的是when thenReturn,但是仍然會執行方法里面的內容
 6         Mockito.when(obj.hello("z3")).thenReturn("hello l4");
 7         
 8         Assert.assertEquals("hello l4",obj.hello("z3"));
 9         
10         Mockito.verify(obj).hello("z3");
11     }

 

 1 //如果既想使用局部模擬,又不想調用到方法里面的內容
 2     @Test
 3     public void testSpy3() {
 4         Class1Mocked obj = Mockito.spy(new Class1Mocked());
 5         
 6         Mockito.doReturn("hello l4").when(obj).hello("z3");
 7         
 8         Assert.assertEquals("hello l4",obj.hello("z3"));
 9         
10         Mockito.verify(obj).hello("z3");
11     }

 

參考博文:java的mock測試框架


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM