5分鐘了解Mockito

jopen 12年前發布 | 18K 次閱讀 5.2.1版本發布

一、什么是mock測試,什么是mock對象?

 

先來看看下面這個示例:

從上圖可以看出如果我們要對A進行測試,那么就要先把整個依賴樹構建出來,也就是BCDE的實例。

 

一種替代方案就是使用mocks

從圖中可以清晰的看出

mock對象就在調試期間用來作為真實對象的替代品

mock測試就是在測試過程中,對那些不容易構建的對象用一個虛擬對象來代替測試的方法就叫mock測試。

知道什么是mock測試后,那么我們就來認識一下mock框架---Mockito

 

二、什么是Mockito

除了有一個好記的名字外,Mockito嘗試用不一樣的方法做mocking測試,是簡單輕量級能夠替代EasyMock的框架。使用簡單,測試代碼可讀性高,豐富的文檔包含在javadoc中,直接在IDE中可查看文檔,實例,說明。更多信息:http://code.google.com/p/mockito/

 

三、Stub和Mock

相同點:Stub和Mock對象都是用來模擬外部依賴,使我們能控制。

不同點:而stub完全是模擬一個外部依賴,用來提供測試時所需要的測試數據。而mock對象用來判斷測試是否能通過,也就是用來驗證測試中依賴對象間的交互能否達到預期。在mocking框架中mock對象可以同時作為stub和mock對象使用,兩者并沒有嚴格區別。 更多信息:http://martinfowler.com/articles/mocksArentStubs.html

 

四、mockito入門實例

Maven依賴:(沒用maven管理的直接忽略)

 

Xml代碼 
  1. <dependencies>     
  2. <dependency>     
  3. <groupId>org.mockito</groupId>     
  4. <artifactId>mockito-all</artifactId>     
  5. <version>1.8.5</version>     
  6. <scope>test</scope>     
  7. </dependency>     
  8. </dependencies>  

 

Java代碼 
  1. import static org.mockito.Mockito.*;   
  2.   
  3. import java.util.List;   
  4.   
  5. import org.junit.Assert;   
  6. import org.junit.Test;   
  7.   
  8. /**  
  9.  *   
  10.  * @author lzjun  
  11.  * @version 0.1  
  12.  * @date 2012-5-5  
  13.  * {@link http://weibo.com/u/1697702241}   
  14.  *  
  15.  */  
  16. public class SimpleTest {   
  17.            
  18.     @Test  
  19.     public void simpleTest(){   
  20.            
  21.         //創建mock對象,參數可以是類,也可以是接口   
  22.         List<String> list = mock(List.class);   
  23.            
  24.         //設置方法的預期返回值   
  25.         when(list.get(0)).thenReturn("helloworld");   
  26.        
  27.         String result = list.get(0);   
  28.            
  29.         //驗證方法調用(是否調用了get(0))   
  30.         verify(list).get(0);   
  31.            
  32.         //junit測試   
  33.         Assert.assertEquals("helloworld", result);   
  34.     }   
  35. }  

好了,五分鐘差不多了,還想繼續了解那就可以往下面看

 

創建mock對象不能對final,Anonymous ,primitive類進行mock。

 

可對方法設定返回異常

 

Java代碼 
  1. when(list.get(1)).thenThrow(new RuntimeException("test excpetion"));  

 

stubbing另一種語法(設置預期值的方法),可讀性不如前者

Java代碼 
  1. doReturn("secondhello").when(list).get(1);  

沒有返回值的void方法與其設定(支持迭代風格,第一次調用donothing,第二次dothrow拋出runtime異常)

Java代碼 
  1. doNothing().doThrow(new RuntimeException("void exception")).when(list).clear();   
  2. list.clear();   
  3. list.clear();   
  4. verify(list,times(2)).clear();  

 

五、參數匹配器(Argument Matcher)

Matchers類內加你有很多參數匹配器  anyInt、anyString、anyMap.....Mockito類繼承于Matchers,Stubbing時使用內建參數匹配器,下例:

 

Java代碼 
  1. @Test  
  2. public void argumentMatcherTest(){   
  3.        
  4.     List<String> list = mock(List.class);   
  5.        
  6.     when(list.get(anyInt())).thenReturn("hello","world");   
  7.        
  8.     String result = list.get(0)+list.get(1);   
  9.        
  10.     verify(list,times(2)).get(anyInt());   
  11.        
  12.     Assert.assertEquals("helloworld", result);   
  13.        
  14. }  

 

 需要注意的是:如果使用參數匹配器,那么所有的參數都要使用參數匹配器,不管是stubbing還是verify的時候都一樣。

 

Java代碼 
  1. @Test  
  2. public void argumentMatcherTest2(){   
  3.        
  4.     Map<Integer,String> map = mock(Map.class);   
  5.     when(map.put(anyInt(),anyString())).thenReturn("hello");//anyString()替換成"hello"就會報錯   
  6.     map.put(1"world");   
  7.     verify(map).put(eq(1), eq("world")); //eq("world")替換成"world"也會報錯   
  8.        
  9. }   

 

 六、方法調用的驗證(具體的調用次數、至少一次,一次也沒有)

 

Java代碼 
  1. @Test  
  2. public void verifyInvocate(){   
  3.        
  4.     List<String> mockedList = mock(List.class);   
  5.     //using mock    
  6.      mockedList.add("once");   
  7.      mockedList.add("twice");   
  8.      mockedList.add("twice");   
  9.         
  10.      mockedList.add("three times");   
  11.      mockedList.add("three times");   
  12.      mockedList.add("three times");   
  13.         
  14.      /**  
  15.       * 基本的驗證方法  
  16.       * verify方法驗證mock對象是否有沒有調用mockedList.add("once")方法  
  17.       * 不關心其是否有返回值,如果沒有調用測試失敗。  
  18.       */  
  19.      verify(mockedList).add("once");    
  20.      verify(mockedList, times(1)).add("once");//默認調用一次,times(1)可以省略   
  21.         
  22.         
  23.      verify(mockedList, times(2)).add("twice");   
  24.      verify(mockedList, times(3)).add("three times");   
  25.         
  26.      //never()等同于time(0),一次也沒有調用   
  27.      verify(mockedList, times(0)).add("never happened");   
  28.         
  29.      //atLeastOnece/atLeast()/atMost()   
  30.      verify(mockedList, atLeastOnce()).add("three times");   
  31.      verify(mockedList, atLeast(2)).add("twice");   
  32.      verify(mockedList, atMost(5)).add("three times");   
  33.   
  34. }  
 

 

一次寫不完,慢慢分析。。。

參考:

http://mockito.googlecode.com/svn/branches/1.6/javadoc/org/mockito/Mockito.html

http://www.sizovpoint.com/2009/03/java-mock-frameworks-comparison.html

http://wenku.baidu.com/view/8def451a227916888486d73f.html

http://qiuguo0205.iteye.com/blog/1443344

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!