一、什么是mock測試崖疤,什么是mock對象猪杭?
先來看看下面這個示例:
從上圖可以看出如果我們要對A進(jìn)行測試,那么就要先把整個依賴樹構(gòu)建出來搂赋,也就是BCDE的實(shí)例。
一種替代方案就是使用mocks
從圖中可以清晰的看出
mock對象就是在調(diào)試期間用來作為真實(shí)對象的替代品益缠。
mock測試就是在測試過程中脑奠,對那些不容易構(gòu)建的對象用一個虛擬對象來代替測試的方法就叫mock測試。
知道什么是mock測試后幅慌,那么我們就來認(rèn)識一下mock框架---Mockito
二宋欺、什么是Mockito
除了有一個好記的名字外,Mockito嘗試用不一樣的方法做mocking測試,是簡單輕量級能夠替代EasyMock的框架齿诞。使用簡單酸休,測試代碼可讀性高,豐富的文檔包含在javadoc中祷杈,直接在IDE中可查看文檔斑司,實(shí)例,說明但汞。更多信息:http://code.google.com/p/mockito/
三宿刮、Stub和Mock
相同點(diǎn):Stub和Mock對象都是用來模擬外部依賴,使我們能控制私蕾。
不同點(diǎn):而stub完全是模擬一個外部依賴僵缺,用來提供測試時所需要的測試數(shù)據(jù)。而mock對象用來判斷測試是否能通過踩叭,也就是用來驗(yàn)證測試中依賴對象間的交互能否達(dá)到預(yù)期磕潮。在mocking框架中mock對象可以同時作為stub和mock對象使用,兩者并沒有嚴(yán)格區(qū)別懊纳。 更多信息:http://martinfowler.com/articles/mocksArentStubs.html
四揉抵、mockito入門實(shí)例
Maven依賴:(沒用maven管理的直接忽略)
Xml代碼
<dependencies>?? ??
<dependency>?? ??
<groupId>org.mockito</groupId>?? ??
<artifactId>mockito-all</artifactId>?? ??
<version>1.8.5</version>?? ??
<scope>test</scope>?? ??
</dependency>?? ??
</dependencies>??
Java代碼
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(){ ??
????????//創(chuàng)建mock對象亡容,參數(shù)可以是類嗤疯,也可以是接口???
????????List<String>?list?=?mock(List.class); ??
????????//設(shè)置方法的預(yù)期返回值???
????????when(list.get(0)).thenReturn("helloworld"); ??
????????String?result?=?list.get(0); ??
????????//驗(yàn)證方法調(diào)用(是否調(diào)用了get(0))???
????????verify(list).get(0); ??
????????//junit測試???
????????Assert.assertEquals("helloworld",?result); ??
????} ??
}??
好了,五分鐘差不多了闺兢,還想繼續(xù)了解那就可以往下面看
創(chuàng)建mock對象不能對final茂缚,Anonymous ,primitive類進(jìn)行mock屋谭。
可對方法設(shè)定返回異常
Java代碼
when(list.get(1)).thenThrow(new?RuntimeException("test?excpetion"));??
stubbing另一種語法(設(shè)置預(yù)期值的方法)脚囊,可讀性不如前者
Java代碼
doReturn("secondhello").when(list).get(1);??
沒有返回值的void方法與其設(shè)定(支持迭代風(fēng)格,第一次調(diào)用donothing,第二次dothrow拋出runtime異常)
Java代碼
doNothing().doThrow(new?RuntimeException("void?exception")).when(list).clear(); ??
list.clear(); ??
list.clear(); ??
verify(list,times(2)).clear();??
五桐磁、參數(shù)匹配器(Argument Matcher)
Matchers類內(nèi)加你有很多參數(shù)匹配器 ?anyInt悔耘、anyString、anyMap.....Mockito類繼承于Matchers,Stubbing時使用內(nèi)建參數(shù)匹配器我擂,下例:
Java代碼
@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); ??
}??
?需要注意的是:如果使用參數(shù)匹配器衬以,那么所有的參數(shù)都要使用參數(shù)匹配器,不管是stubbing還是verify的時候都一樣校摩。
Java代碼
@Test??
public?void?argumentMatcherTest2(){ ??
????Map<Integer,String>?map?=?mock(Map.class); ??
????when(map.put(anyInt(),anyString())).thenReturn("hello");//anyString()替換成"hello"就會報(bào)錯???
????map.put(1,?"world"); ??
????verify(map).put(eq(1),?eq("world"));?//eq("world")替換成"world"也會報(bào)錯???
} ??
?六看峻、方法調(diào)用的驗(yàn)證(具體的調(diào)用次數(shù)、至少一次衙吩,一次也沒有)
Java代碼
@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"); ??
?????/**?
*?基本的驗(yàn)證方法?
*?verify方法驗(yàn)證mock對象是否有沒有調(diào)用mockedList.add("once")方法?
*?不關(guān)心其是否有返回值互妓,如果沒有調(diào)用測試失敗。?
??????*/??
?????verify(mockedList).add("once");? ??
?????verify(mockedList,?times(1)).add("once");//默認(rèn)調(diào)用一次,times(1)可以省略???
?????verify(mockedList,?times(2)).add("twice"); ??
?????verify(mockedList,?times(3)).add("three?times"); ??
?????//never()等同于time(0),一次也沒有調(diào)用???
?????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