5分鐘瞭解Mockito

1、什麼是mock測試,什麼是mock對象?html

 

先來看看下面這個示例:java

從上圖能夠看出若是咱們要對A進行測試,那麼就要先把整個依賴樹構建出來,也就是BCDE的實例。app

 

一種替代方案就是使用mocks框架

從圖中能夠清晰的看出maven

mock對象就是在調試期間用來做爲真實對象的替代品。svn

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

知道什麼是mock測試後,那麼咱們就來認識一下mock框架---Mockitogoogle

 

2、什麼是Mockitospa

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

 

3、Stub和Mock

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

不一樣點:而stub徹底是模擬一個外部依賴,用來提供測試時所須要的測試數據。而mock對象用來判斷測試是否能經過,也就是用來驗證測試中依賴對象間的交互可否達到預期。在mocking框架中mock對象能夠同時做爲stub和mock對象使用,二者並無嚴格區別。 更多信息:http://martinfowler.com/articles/mocksArentStubs.html

 

4、mockito入門實例

Maven依賴:(沒用maven管理的能夠下載相關jar包導入classpath)

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-all</artifactId>
    <version>1.9.5</version>
    <scope>test</scope>
</dependency>

 

import static org.mockito.Mockito.*;

import java.util.List;

import org.junit.Assert;
import org.junit.Test;

/**
 * 
 * @author lzjun
 * @version 0.1
 * @date 2012-5-5
 * {@link http://weibo.com/u/1697702241} 
 *
 */
public class SimpleTest {
		
	@Test
	public void simpleTest(){
		
		//建立mock對象,參數能夠是類,也能夠是接口
		List<String> list = mock(List.class);
		
		//設置方法的預期返回值
		when(list.get(0)).thenReturn("helloworld");
	
		String result = list.get(0);
		
		//驗證方法調用(是否調用了get(0))
		verify(list).get(0);
		
		//junit測試
		Assert.assertEquals("helloworld", result);
	}
}

好了,五分鐘差很少了,還想繼續瞭解那就能夠往下面看

 

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

 

可對方法設定返回異常

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

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

doReturn("secondhello").when(list).get(1);

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

doNothing().doThrow(new RuntimeException("void exception")).when(list).clear();  
list.clear();  
list.clear();  
verify(list,times(2)).clear()

5、參數匹配器(Argument Matcher)

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

@Test
public void argumentMatcherTest(){
    
    List<String> list = mock(List.class);
    
    when(list.get(anyInt())).thenReturn("hello","world");
    
    String result = list.get(0)+list.get(1);
    
    verify(list,times(2)).get(anyInt());
    
    Assert.assertEquals("helloworld", result);
    
}

 須要注意的是:若是使用參數匹配器,那麼全部的參數都要使用參數匹配器,無論是stubbing仍是verify的時候都同樣。

@Test
public void argumentMatcherTest2(){
    
    Map<Integer,String> map = mock(Map.class);
    when(map.put(anyInt(),anyString())).thenReturn("hello");//anyString()替換成"hello"就會報錯
    map.put(1, "world");
    verify(map).put(eq(1), eq("world")); //eq("world")替換成"world"也會報錯
    
}

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

@Test
public void verifyInvocate(){
    
    List<String> mockedList = mock(List.class);
    //using mock 
     mockedList.add("once");
     mockedList.add("twice");
     mockedList.add("twice");
     
     mockedList.add("three times");
     mockedList.add("three times");
     mockedList.add("three times");
     
     /**
      * 基本的驗證方法
      * verify方法驗證mock對象是否有沒有調用mockedList.add("once")方法
      * 不關心其是否有返回值,若是沒有調用測試失敗。
      */
     verify(mockedList).add("once"); 
     verify(mockedList, times(1)).add("once");//默認調用一次,times(1)能夠省略
     
     
     verify(mockedList, times(2)).add("twice");
     verify(mockedList, times(3)).add("three times");
     
     //never()等同於time(0),一次也沒有調用
     verify(mockedList, times(0)).add("never happened");
     
     //atLeastOnece/atLeast()/atMost()
     verify(mockedList, atLeastOnce()).add("three times");
     verify(mockedList, atLeast(2)).add("twice");
     verify(mockedList, atMost(5)).add("three times");

}

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

參考:

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

相關文章
相關標籤/搜索