麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁(yè) > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

how to learn unit test mock framework

2019-11-11 05:08:22
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

refer to http://www.strolling.cn/2017/01/how_to_learn_unit_test_mock_framework/

每次使用各種形形色色的單元測(cè)試Mock框架都比較暈,因?yàn)閷懙牟粔蚨啵葘W(xué)會(huì)了,又流行了一個(gè)新的框架,思考為什么老是記不住以及為什么每次都不能胸有成竹的說(shuō)自己掌握了,想想估計(jì)是因?yàn)槊看味际乾F(xiàn)學(xué)現(xiàn)用,比較零散,不成體系,所以寫下這個(gè)記錄,匯總下到底應(yīng)該學(xué)習(xí),一方面可以幫助在新學(xué)一個(gè)單元測(cè)試mock框架的時(shí)候,按照這個(gè)順序?qū)W,學(xué)完之后,按照這個(gè)步驟寫CASE;另一方面在使用mockito/powermock時(shí),直接根據(jù)場(chǎng)景復(fù)制代碼。

必知必會(huì)(一)- 搞出“假”對(duì)象

既然是單元測(cè)試的Mock使用, 第一步要學(xué)的是怎么搞出一個(gè)假的對(duì)象,然后后續(xù)工作其實(shí)都是圍繞這個(gè)假對(duì)象做文章。

根據(jù)應(yīng)用場(chǎng)景不同可以劃分為2種方式:

(1)Mock: 制造一個(gè)完全的假對(duì)象;

根據(jù)策略的不同,可以定義不同默認(rèn)行為的假對(duì)象,例如:

所有方法不進(jìn)行任何真實(shí)調(diào)用,都統(tǒng)一返回null;

Apple apple= Mockito.mock(Apple.class);

所有方法調(diào)用是真實(shí)調(diào)用

Apple apple= Mockito.mock(Apple.class,Mockito.CALLS_REAL_METHODS);

(2)Spy: 制造一個(gè)假對(duì)象,但是是基于已有一個(gè)真實(shí)的對(duì)象。

滿足的需求是,大多方法想用真實(shí)實(shí)例來(lái)調(diào)用,只想定制實(shí)例內(nèi)部的一些方法。

Apple apple = new Apple();Apple spiedApple= Mockito.spy(apple);

必知必會(huì)(二)- 綁定上“假”對(duì)象

第一步搞出假對(duì)象后,不會(huì)就自動(dòng)使用上了,否則別人不需要用mock的測(cè)試怎么測(cè)?所以第二步要做的是讓自己的Mock對(duì)象使用上,即綁定上被測(cè)目標(biāo)和mocked對(duì)象,思考一個(gè)類如何使用另外一個(gè)類:

1 被測(cè)目標(biāo)自己不創(chuàng)建,而是需要使用者傳遞進(jìn)去的方式:

(a)作為構(gòu)造器參數(shù)直接傳遞進(jìn)去; (b)使用Set系方法傳遞進(jìn)去;

2 被測(cè)目標(biāo)負(fù)責(zé)創(chuàng)建

本質(zhì)上創(chuàng)建都是new的過(guò)程(PS:除了靜態(tài)類), 所以mock掉new,讓new返回要mocked的對(duì)象,就搞定所有的事情,但是從被測(cè)目標(biāo)看,不可能都是new,可能這個(gè)new離被測(cè)目標(biāo)還是有一定的距離:例如使用工廠類,使用sPRing的@autowire的等等,所以從代碼層次看有以下幾種情況:

(1) Apple apple = new Apple();(2) apple = AppleFactory.getIntance();(3)@Autowiredprivate Apple apple;

(a)針對(duì)直接new的方式:讓new出一個(gè)對(duì)象都返回mock的實(shí)例

class AppleTree{private Apple apple= new Apple();}@RunWith(PowerMockRunner.class)@PrepareForTest({AppleTree.class}) //don't miss this statement and pay more attention it is caller for Apple, not Apple.public class TestNewObject { @Testpublic void test() throws Exception {Apple apple= Mockito.mock(Apple.class);PowerMockito.whenNew(Apple.class).withNoArguments().thenReturn(apple);}

(b)針對(duì)使用其他類來(lái)創(chuàng)建:mock創(chuàng)建方法

一般都是靜態(tài)工廠這種情況,如果不是“靜態(tài)工廠”,是另外一個(gè)實(shí)例的普通方法創(chuàng)建的,則需要mock那個(gè)實(shí)例了。 這里僅考慮一般情況,即面對(duì)靜態(tài)工廠方法,mockito暫時(shí)不支持靜態(tài)類的mock,所以需要結(jié)合powermock:

@RunWith(PowerMockRunner.class)@PrepareForTest({AppleFactory.class}) //don't miss this statementpublic class TestStaticMethod {@Testpublic void test() throws Exception {Apple apple= Mockito.mock(Apple.class);PowerMockito.mockStatic(AppleFactory.class);PowerMockito.when(AppleFactory.getInstance()).thenReturn(apple);}

(c)還有一種情況是使用框架自動(dòng)創(chuàng)建的,例如使用Spring的@Autowired 此時(shí)可以使用java反射來(lái)直接設(shè)置進(jìn)去,但是既然是使用mock工具,也可以使用標(biāo)準(zhǔn)點(diǎn)的方式,例如:

Apple apple= Mockito.mock(Apple.class);Whitebox.setInternalState(testAppleInstance, "apple", apple);

必知必會(huì)(三)- Mock對(duì)象上做文章-偽造行為

學(xué)完前面2步后,就可以開始考慮干活了,既然搞出假的mock對(duì)象,不可能不去做一些“假動(dòng)作”: 匹配上一個(gè)方法,然后做出一個(gè)行為:

其中匹配包括2種:

粗略匹配:

Mockito.when(mockedApple.getOwner(Mockito.anyString()).thenReturn("tom");

精確匹配:

Mockito.when(mockedApple.getOwner(Mockito.eq("somegstring"))).thenReturn("tom");

行為包括以下三種:

(1) 定義方法非真實(shí)調(diào)用;

設(shè)置其返回值:

Mockito.when(mockedApple.getOwner()).thenReturn("tom");

設(shè)置其拋出異常:

Mockito.when(mockedApple.getOwner()).thenThrow(new RuntimeException());

(2)定義方法去進(jìn)行真實(shí)調(diào)用:

Mockito.when(mockedApple.getNumbers()).thenCallRealMethod();

(3)自適應(yīng)變化:

例如設(shè)置每次返回的不同可以使用:

when(mockedApple.getOwner()) .thenReturn("one") //第一次行為 .thenCallRealMethod() //第二次行為 .thenThrow(new RuntimeException()); //第三次行為

其他形式的各種高級(jí)搞法,不考慮。

必知必會(huì)(四)- Mock對(duì)象上做文章-驗(yàn)證行為

不考慮本身case就可以寫出驗(yàn)證點(diǎn),有時(shí)候需要驗(yàn)證一些mocked對(duì)象上的行為來(lái)驗(yàn)證case是否成功,按照需要驗(yàn)證的要點(diǎn)來(lái)看: (1)驗(yàn)證調(diào)用與否或調(diào)用次數(shù)

Mockito.verify(mockedApple, Mockito.times(2)).someMethod(Mockito.anyString()); Mockito.verify(mockedApple, Mockito.never()).someMethod(Mockito.anyString());

(2) 驗(yàn)證調(diào)用時(shí)間

Mockito.verify(mockedApple, Mockito.timeout(10)).someMethod(Mockito.anyString());

(3)驗(yàn)證調(diào)用參數(shù)值

方式1:Matcher-直接驗(yàn)證參數(shù)

簡(jiǎn)單校驗(yàn):

Mockito.verify(mockedApple, times(2)).someMethod(Mockito.eq("expectedString")); //mockito要求此處不能直接寫"expectedString"

自動(dòng)義校驗(yàn)方法:

使用Mockito.argThat+ArgumentMatcher(Matchers.argThat(Matcher matcher) ):

Mockito.verify(mockedApple).someMethod(Mockito.argThat(new ArgumentMatcher<String>(){ @Override public boolean matches(String argument) { return argument.equals("expectedString");}}));

方式2:Captor-捕獲出參數(shù),然后校驗(yàn)

使用ArgumentCaptor捕獲參數(shù),然后進(jìn)一步處理的

ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);Mockito.verify(mockedApple).someMethod(argument.capture());String value = argument.getValue();Assert.assertEqual(value, expectedString);

區(qū)別: Also, sometimes ArgumentCaptor may be a better fit than custom matcher. For example, if custom argument matcher is not likely to be reused or you just need it to assert on argument values to complete verification of behavior.

(4) 驗(yàn)證調(diào)用順序

主要包括兩種,一種是同一個(gè)mock對(duì)象的方法調(diào)用順序,另外一種是跨mock對(duì)象的方法調(diào)用順序驗(yàn)證,分別參考一下兩種示例:

InOrder inOrder = Mockito.inOrder(mockedApple);inOrder.verify(mockedApple).firstMethodCallName();inOrder.verify(mockedApple).secondMethodCallName();InOrder inOrder = Mockito.inOrder(mockedApple,mockedOrange);inOrder.verify(mockedApple).methodCallName();inOrder.verify(mockedOrange).methodCallName();

對(duì)于各種驗(yàn)證,有時(shí)候需要reset mock對(duì)象,以便處理共享等問(wèn)題,可以使用Mockito.reset()。

總結(jié):

對(duì)于一個(gè)新的單元測(cè)試框架大體要搞清楚幾件事情:“偽造對(duì)象-綁定對(duì)象-定制對(duì)象動(dòng)作-驗(yàn)證” ,核心關(guān)鍵是mock/spy it then when customized match one method do something and verify after executed寫具體case的時(shí)候,也可以follow四個(gè)步驟來(lái)搞。另外上面演示的都是基本要點(diǎn),其他都是各種形式的變種或高級(jí)用法,同時(shí)每種框架都有自己的特殊要求,必須遵從。


上一篇:正交基

下一篇:PAT BASIC 1003

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 免费a级网站| 国产中出在线观看 | xfplay噜噜av| 黑人一区二区三区四区五区 | 国产成人高潮免费观看精品 | 欧洲成人精品 | 91美女福利视频 | 蜜桃av网| 日韩精品久久久 | 日日草天天干 | 国产成年人小视频 | 国产在线地址 | 日韩精品 | 免费高潮在线国 | 国产无遮挡一区二区三区毛片日本 | 欧美精品一区二区三区在线 | 国产一级二级在线播放 | 国产精品久久久久久久av三级 | 欧美自拍三区 | 国产精品久久久久久久久久三级 | 亚洲欧洲日产v特级毛片 | 717影院理论午夜伦八戒秦先生 | 免费国产视频在线观看 | 日韩欧美高清片 | xnxx 日本免费 | 福利一区二区三区视频在线观看 | 欧美一级免费视频 | 欧美视频在线一区二区三区 | 国产69精品久久久久99尤 | 轻点插视频 | 蜜桃网站免费 | 色柚视频网站ww色 | 国产91中文字幕 | 有色视频在线观看 | 久久久久久久不卡 | 亚洲婷婷日日综合婷婷噜噜噜 | 国产精品一区视频 | 免费看日韩av | 毛片免费大全短视频 | 久久国产精品一区 | 在线播放一区二区三区 |