亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

歡迎使用CSDN-markdown編輯器

2019-11-11 06:19:01
字體:
來源:轉載
供稿:網友

每次使用各種形形色色的單元測試Mock框架都比較暈,因為寫的不夠多,等學會了,又流行了一個新的框架,思考為什么老是記不住以及為什么每次都不能胸有成竹的說自己掌握了,想想估計是因為每次都是現學現用,比較零散,不成體系,所以寫下這個記錄,匯總下到底應該學習,一方面可以幫助在新學一個單元測試mock框架的時候,按照這個順序學,學完之后,按照這個步驟寫CASE;另一方面在使用mockito/powermock時,直接根據場景復制代碼。

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

既然是單元測試的Mock使用, 第一步要學的是怎么搞出一個假的對象,然后后續工作其實都是圍繞這個假對象做文章。

根據應用場景不同可以劃分為2種方式:

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

根據策略的不同,可以定義不同默認行為的假對象,例如:

所有方法不進行任何真實調用,都統一返回null;

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

所有方法調用是真實調用

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

(2)Spy: 制造一個假對象,但是是基于已有一個真實的對象。

滿足的需求是,大多方法想用真實實例來調用,只想定制實例內部的一些方法。

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

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

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

1 被測目標自己不創建,而是需要使用者傳遞進去的方式:

(a)作為構造器參數直接傳遞進去; (b)使用Set系方法傳遞進去;

2 被測目標負責創建

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

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

(a)針對直接new的方式:讓new出一個對象都返回mock的實例

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)針對使用其他類來創建:mock創建方法

一般都是靜態工廠這種情況,如果不是“靜態工廠”,是另外一個實例的普通方法創建的,則需要mock那個實例了。 這里僅考慮一般情況,即面對靜態工廠方法,mockito暫時不支持靜態類的mock,所以需要結合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)還有一種情況是使用框架自動創建的,例如使用Spring的@Autowired 此時可以使用java反射來直接設置進去,但是既然是使用mock工具,也可以使用標準點的方式,例如:

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

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

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

其中匹配包括2種:

粗略匹配:

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

精確匹配:

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

行為包括以下三種:

(1) 定義方法非真實調用;

設置其返回值:

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

設置其拋出異常:

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

(2)定義方法去進行真實調用:

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

(3)自適應變化:

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

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

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

必知必會(四)- Mock對象上做文章-驗證行為

不考慮本身case就可以寫出驗證點,有時候需要驗證一些mocked對象上的行為來驗證case是否成功,按照需要驗證的要點來看: (1)驗證調用與否或調用次數

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

(2) 驗證調用時間

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

(3)驗證調用參數值

方式1:Matcher-直接驗證參數

簡單校驗:

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

自動義校驗方法:

使用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-捕獲出參數,然后校驗

使用ArgumentCaptor捕獲參數,然后進一步處理的

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

區別: 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) 驗證調用順序

主要包括兩種,一種是同一個mock對象的方法調用順序,另外一種是跨mock對象的方法調用順序驗證,分別參考一下兩種示例:

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();

對于各種驗證,有時候需要reset mock對象,以便處理共享等問題,可以使用Mockito.reset()。

總結:

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


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
2019中文字幕免费视频| 久久亚洲电影天堂| 国产亚洲aⅴaaaaaa毛片| 日韩在线中文字| 欧美性xxxx在线播放| 欧美天堂在线观看| 成人激情视频免费在线| 国产精品久久中文| 91免费视频国产| 欧美裸体xxxx极品少妇软件| 自拍偷拍免费精品| 92看片淫黄大片欧美看国产片| 久久久精品在线观看| 午夜精品一区二区三区视频免费看| 伊人伊成久久人综合网小说| 欧美电影在线免费观看网站| 超碰日本道色综合久久综合| 国产午夜精品一区理论片飘花| 亚洲黄色成人网| 国产亚洲欧洲高清一区| 久久韩国免费视频| 欧美中文字幕视频在线观看| 欧美综合国产精品久久丁香| 国产精品美女www爽爽爽视频| www.久久草.com| 日韩大片免费观看视频播放| 日韩高清电影免费观看完整| 国产精品小说在线| 成人欧美一区二区三区黑人孕妇| 韩国日本不卡在线| 一本大道久久加勒比香蕉| 亚洲性视频网址| 国产精品羞羞答答| 4k岛国日韩精品**专区| 欧美成人精品影院| 亚洲国产精久久久久久久| 国产综合视频在线观看| 久久久91精品国产| 6080yy精品一区二区三区| 91精品国产自产在线老师啪| 成人久久一区二区三区| 69久久夜色精品国产69| 九九视频这里只有精品| 精品亚洲国产成av人片传媒| 国产精品永久在线| 久久精品影视伊人网| 中文字幕亚洲二区| 中文字幕综合一区| 欧美黑人巨大xxx极品| 亚洲国产精品久久久久秋霞不卡| 国产精品aaaa| 欧美一级在线亚洲天堂| 国产精品亚洲一区二区三区| 国产视频亚洲视频| 久久久在线视频| 精品国产一区二区三区久久狼5月| 久久影视电视剧凤归四时歌| 亚洲精品一区av在线播放| 在线日韩中文字幕| 亚洲性夜色噜噜噜7777| 91精品视频播放| 日本亚洲欧美成人| 成人黄色免费片| 久久久久久国产精品三级玉女聊斋| 神马久久桃色视频| 久久久久www| 在线精品国产欧美| 91久久精品国产| 4438全国亚洲精品在线观看视频| 91精品视频专区| 欧美综合在线第二页| 国产精品成人免费电影| 中文字幕在线日韩| 亚洲视频999| 2018中文字幕一区二区三区| 久久久久久国产免费| 亚洲性日韩精品一区二区| 欧美成人剧情片在线观看| 91av在线免费观看视频| 亚洲奶大毛多的老太婆| 色悠久久久久综合先锋影音下载| 精品国产999| 日韩精品视频在线观看网址| 55夜色66夜色国产精品视频| 中文字幕av一区| 亚洲全黄一级网站| 欧美日韩国产一区二区三区| 欧美一级高清免费| 视频在线一区二区| 日本国产高清不卡| 亚洲天堂2020| 亚洲奶大毛多的老太婆| 久久精品国产v日韩v亚洲| 69**夜色精品国产69乱| 欧美精品一二区| 亚洲视频欧洲视频| 日本电影亚洲天堂| 久久久之久亚州精品露出| 欧美激情乱人伦一区| 国内精品久久久久伊人av| 蜜臀久久99精品久久久久久宅男| 日韩高清免费观看| 亚洲一区中文字幕| 日韩av毛片网| 亚洲国产精品电影在线观看| 亚洲国产美女精品久久久久∴| 91精品国产91久久久| 日韩一区二区福利| 欧美一级大片在线免费观看| 亚洲欧美一区二区激情| 日韩一区二区三区在线播放| 久久国产精品电影| 亚洲欧美制服第一页| 久久视频这里只有精品| 97人洗澡人人免费公开视频碰碰碰| 欧美激情视频在线| 亚洲成人精品久久久| 欧美日韩综合视频| 亚洲a∨日韩av高清在线观看| 91精品久久久久久久久久入口| 日韩精品丝袜在线| 国产精品免费观看在线| 日韩免费av一区二区| 亚洲第一综合天堂另类专| 色偷偷888欧美精品久久久| 亚洲精品福利在线| 欧美老女人在线视频| 26uuu另类亚洲欧美日本一| 成人免费视频在线观看超级碰| 久久精品91久久香蕉加勒比| 久久免费视频这里只有精品| 亚洲аv电影天堂网| 亚洲韩国欧洲国产日产av| 精品高清一区二区三区| 欧美午夜激情视频| 国产香蕉一区二区三区在线视频| 狠狠综合久久av一区二区小说| 欧美激情精品久久久久久免费印度| 欧美一级淫片aaaaaaa视频| 国产精品久久久久久久久久久久| 日韩av男人的天堂| 黄色一区二区在线观看| 国产女精品视频网站免费| 欧美激情在线视频二区| 5566成人精品视频免费| 国产视频观看一区| 欧美xxxx综合视频| 亚洲成人精品av| 欧美日韩国产中文字幕| 国产精品专区第二| 精品久久中文字幕久久av| 国产亚洲精品久久| 在线精品高清中文字幕| 欧美日韩成人在线观看| 夜夜嗨av色一区二区不卡| 精品福利免费观看| 精品亚洲精品福利线在观看| 在线日韩日本国产亚洲| 性欧美办公室18xxxxhd| 欧美性生活大片免费观看网址| 日韩av电影手机在线| 色综合视频一区中文字幕| 国产精品爽爽ⅴa在线观看| 91国产高清在线|