Moq常用測(cè)試方法

測(cè)試方法

?1?//??準(zhǔn)備?Mock?IFoo?接口??2?var?mock??=???new??Mock?<?IFoo?>?();

?3?//??配置準(zhǔn)備模擬的方法猬仁,當(dāng)調(diào)用接口中的?DoSomething?方法逐虚,并傳遞參數(shù)?"bing"?的時(shí)候叭爱,返回?true??4?mock.Setup(foo??=>??foo.DoSomething(?"?ping?"?)).Returns(?true?);

?5??6?//?方法的參數(shù)中使用了?out?參數(shù)

?7?//??out?arguments???8?var?outString??=???"?ack?"?;

?9?//??當(dāng)調(diào)用?TryParse?方法的時(shí)候买雾,out?參數(shù)返回?"ack",?方法返回?true,?lazy?evaluated??10?mock.Setup(foo??=>??foo.TryParse(?"?ping?"?,??out??outString)).Returns(?true?);

11?12?//??ref?參數(shù)?13?var?instance??=???new?Bar();

14?//??僅僅在使用?ref?調(diào)用的時(shí)候漓穿,才會(huì)匹配下面的測(cè)試?15?mock.Setup(foo??=>??foo.Submit(?ref??instance)).Returns(?true?);

16?17?//?當(dāng)方法返回值得時(shí)候晃危,還可以訪問(wèn)返回的值

18?//??這里可以使用多個(gè)參數(shù)?19?mock.Setup(x??=>??x.DoSomething(It.IsAny?<?string?>?()))

20??????????????????.Returns((?string??s)??=>?s.ToLower());

21?22?//??在被調(diào)用的時(shí)候拋出異常?23?mock.Setup(foo??=>??foo.DoSomething(?"?reset?"?)).Throws?<?InvalidOperationException?>();

24?mock.Setup(foo??=>??foo.DoSomething(?""?)).Throws(?new??ArgumentException(?"?command?"?);

25?26?//??延遲計(jì)算返回的結(jié)果??27?mock.Setup(foo??=>??foo.GetCount()).Returns(()??=>?count);

28?29?//??在每一次調(diào)用的時(shí)候僚饭,返回不同的值??30?var?mock??=???new??Mock?<?IFoo?>?();

31?var?calls??=???0?;

32?mock.Setup(foo??=>?foo.GetCountThing())

33??????.Returns(()??=>?calls)

34??????.Callback(()??=>??calls?++?);

35?36?//??第一次調(diào)用返回?0苇瓣,?下一次是?1偿乖,?依次類推?37?Console.WriteLine(mock.Object.GetCountThing());


匹配參數(shù)

?1?//??任意值???2?mock.Setup(foo??=>??foo.DoSomething(It.IsAny?<?string?>?())).Returns(?true?);

?3??4?//??提供的值必須匹配一個(gè)函數(shù),?lazy?evaluated???5?mock.Setup(foo??=>??foo.Add(It.Is?<?int?>?(i??=>??i??%???2???==???0?))).Returns(?true?);

?6??7?//??匹配一個(gè)范圍???8?mock.Setup(foo??=>??foo.Add(It.IsInRange?<?int?>?(?0?,??10?,?Range.Inclusive))).Returns(?true);

?9?10?//??匹配正則表達(dá)式?11?mock.Setup(x??=>??x.DoSomething(It.IsRegex(?"?[a-d]+?"?,?RegexOptions.IgnoreCase))).Returns(?"?foo?"?);


屬性

?1?//??普通屬性??2?mock.Setup(foo??=>??foo.Name).Returns(?"?bar?"?);

?3??4?//??多層的屬性??5?mock.Setup(foo??=>??foo.Bar.Baz.Name).Returns(?"?baz?"?);

?6??7?//??期望設(shè)置屬性的值為?"foo"???8?mock.SetupSet(foo??=>??foo.Name??=???"?foo?"?);

?9?10?//??或者直接驗(yàn)證賦值??11?mock.VerifySet(foo??=>??foo.Name??=???"?foo?"?);


設(shè)置屬性媳禁,以便自動(dòng)跟蹤它的值

?1?//??開(kāi)始?"tracking"?屬性的?sets/gets???2?mock.SetupProperty(f??=>?f.Name);

?3??4?//??提供一個(gè)默認(rèn)的值??5?mock.SetupProperty(f??=>??f.Name,??"?foo?"?);

?6??7?//??現(xiàn)在损话,你可以:????8?IFoo?foo??=?mock.Object;

?9?10?//??保存的值??11?Assert.Equal(?"?foo?"?,?foo.Name);

12?13?//??重新設(shè)置一個(gè)值?14?foo.Name??=???"?bar?"?;

15?Assert.Equal(?"?bar?"?,?foo.Name);


還可以準(zhǔn)備所有的屬性

mock.SetupAllProperties();


事件

?1?//??拋出一個(gè)事件???2?mock.Raise(m??=>??m.FooEvent??+=???null?,??new?FooEventArgs(fooValue));

?3??4?//??多層的后代中的事件???5?mock.Raise(m??=>??m.Child.First.FooEvent??+=???null?,??new?FooEventArgs(fooValue));

?6??7?//??當(dāng)?Submit?方法被調(diào)用的時(shí)候,拋出一個(gè)事件???8?mock.Setup(foo??=>??foo.Submit()).Raises(f??=>??f.Sent??+=???null?,?EventArgs.Empty);

?9?10?//?拋出異常將會(huì)觸發(fā)對(duì)象底層的行為

11?//?你可能需要在后面進(jìn)行斷言處理

12?13?//??拋出一個(gè)自定義的事件?14?public???delegate???void??MyEventHandler(?int??i,??bool?b);

15?public???interface??IFoo?{????event?MyEventHandler?MyEvent;??}

16?var?mock??=???new??Mock?<?IFoo?>?();

17?...

18?19?//??傳遞自定義的事件參數(shù)?20?mock.Raise(foo??=>??foo.MyEvent??+=???null?,??25?,??true?);


?回調(diào)

?1?var?mock??=???new??Mock?<?IFoo?>?();

?2?mock.Setup(foo??=>??foo.Execute(?"?ping?"?))

?3??????.Returns(?true?)

?4??????.Callback(()??=>??calls?++?);

?5??6?//??使用調(diào)用的參數(shù)???7?mock.Setup(foo??=>??foo.Execute(It.IsAny?<?string?>?()))

?8??????.Returns(?true?)

?9??????.Callback((?string??s)??=>?calls.Add(s));

10?11?//??使用泛型語(yǔ)法??12?mock.Setup(foo??=>??foo.Execute(It.IsAny?<?string?>?()))

13??????.Returns(?true?)

14??????.Callback?<?string?>?(s??=>?calls.Add(s));

15?16?//??使用多個(gè)參數(shù)?17?mock.Setup(foo??=>??foo.Execute(It.IsAny?<?int?>?(),?It.IsAny?<?string?>?()))

18??????.Returns(?true?)

19??????.Callback?<?int?,??string?>?((i,?s)??=>?calls.Add(s));

20?21?//??調(diào)用之前和之后的回調(diào)??22?mock.Setup(foo??=>??foo.Execute(?"?ping?"?))

23??????.Callback(()??=>??Console.WriteLine(?"?Before?returns?"?))

24??????.Returns(?true?)

25??????.Callback(()??=>??Console.WriteLine(?"?After?returns?"?));


驗(yàn)證

?1?mock.Verify(foo??=>??foo.Execute(?"?ping?"?));

?2??3?//??在驗(yàn)證失敗的時(shí)候,提供自定義的錯(cuò)誤提示信息???4?mock.Verify(foo??=>??foo.Execute(?"?ping?"?),??"?When?doing?operation?X,?the?service?should?be?pinged?always?"?);

?5??6?//??從沒(méi)有被調(diào)用的方法???7?mock.Verify(foo??=>??foo.Execute(?"?ping?"?),?Times.Never());

?8??9?//??至少調(diào)用過(guò)一次??10?mock.Verify(foo??=>??foo.Execute(?"?ping?"?),?Times.AtLeastOnce());

11?mock.VerifyGet(foo??=>?foo.Name);

12?13?//??驗(yàn)證對(duì)屬性的賦值.??14?mock.VerifySet(foo??=>?foo.Name);

15?16?//??驗(yàn)證對(duì)于屬性設(shè)置特定的值??17?mock.VerifySet(foo??=>??foo.Name??=?"?foo?"?);

18?19?//??驗(yàn)證匹配的參數(shù)??20?mock.VerifySet(foo??=>??foo.Value??=??It.IsInRange(?1?,??5?,?Range.Inclusive));


?自定義 Mock 行為

Mock 的行為分為嚴(yán)格的 Strict 和寬松的 Loose, 默認(rèn)為寬松的债沮。在嚴(yán)格模式下疫衩,使用任何沒(méi)有被指定的行為闷煤,都將會(huì)拋出異常鲤拿,寬松模式下,不會(huì)拋出任何異常,方法將會(huì)返回默認(rèn)值或者空的數(shù)組等等久锥。

var?mock??=???new??Mock?<?IFoo?>?(MockBehavior.Strict);


如果沒(méi)有重寫基類的實(shí)現(xiàn),默認(rèn)將不會(huì)調(diào)用基類冤寿,在 Mock Web/Html 控件的是必須的督怜。

var?mock??=???new??Mock?<?IFoo?>??{?CallBase??=???true??};


?創(chuàng)造自動(dòng)遞歸的 Mock, Mock 對(duì)象對(duì)于它的任何成員將會(huì)返回一個(gè)新的 Mock 對(duì)象号杠。


var?mock??=???new??Mock?<?IFoo?>??{?DefaultValue??=?DefaultValue.Mock?};

//?默認(rèn)是?DefaultValue.Empty

//??現(xiàn)在這個(gè)屬性將會(huì)返回一個(gè)新的?Mock?對(duì)象??IBar?value??=?mock.Object.Bar;

//?可以使用返回的?Mock?對(duì)象,?后即對(duì)屬性的訪問(wèn)返回相同的對(duì)象實(shí)例

//?這就允許我們可以進(jìn)行后繼的設(shè)置

//??set?further?expectations?on?it?if?we?want??var?barMock??=?Mock.Get(value);

barMock.Setup(b

?=>??b.Submit()).Returns(?true?);


中心化的 Mock 實(shí)例創(chuàng)建和管理:你可以在一個(gè)地方使用 MockRepository 創(chuàng)建和驗(yàn)證所有的 Mock 對(duì)象,設(shè)置 MockBehavior, CallBse 和 DefaultValue 約束眼溶。

var?factory??=???new??MockFactory(MockBehavior.Strict)?{?DefaultValue??=?DefaultValue.Mock?};

//??創(chuàng)建?Mock?對(duì)象?var?fooMock??=??factory.Create?<?IFoo?>?();

//??在創(chuàng)建的時(shí)候重寫倉(cāng)庫(kù)的設(shè)置??var?barMock??=??factory.Create?<?IBar?>?(MockBehavior.Loose);

//??驗(yàn)證通過(guò)倉(cāng)庫(kù)創(chuàng)建的對(duì)象??factory.Verify();


其它

//??用在測(cè)試用例的開(kāi)始??using?Moq.Protected()

//??測(cè)試中?var?mock??=???new??Mock?<?CommandBase?>?();?mock.Protected()

.Setup

?<?int?>?(?"?Execute?"?)

.Returns(

?5?);

//?如果用到了參數(shù)匹配,?必須使用?ItExpr?來(lái)代替?It

//??以后計(jì)劃改進(jìn)?mock.Protected()

.Setup

?<?string?>?(?"?Execute?"?,?????????ItExpr.IsAny?<?string?>?())

.Returns(

?true?);


高級(jí)特性

?1?//??從?Mock?實(shí)例重新獲得?Mock?對(duì)象??2?IFoo?foo??=???//??get?mock?instance?somehow???3?var?fooMock??=?Mock.Get(foo);

?4?fooMock.Setup(f??=>??f.Submit()).Returns(?true?);

?5??6?//??實(shí)現(xiàn)多個(gè)接口???7?var?foo??=???new??Mock?<?IFoo?>?();

?8?var?disposableFoo??=??foo.As?<?IDisposable?>?();

?9?10?//?現(xiàn)在?IFoo?mock?已經(jīng)實(shí)現(xiàn)了接口?IDisposable?:)?disposableFoo.Setup(df?=>?df.Dispose());

11?12?//??定制匹配??13?mock.Setup(foo??=>??foo.Submit(IsLarge())).Throws?<?ArgumentException?>?();?...

14?public???string?IsLarge()

15?{

16??????return??Match?<?string?>?.Create(s??=>???!?String.IsNullOrEmpty(s)??&&??s.Length??>???100);

17?}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末绑咱,一起剝皮案震驚了整個(gè)濱河市铝噩,隨后出現(xiàn)的幾起案子薄榛,更是在濱河造成了極大的恐慌敞恋,老刑警劉巖硬猫,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件坑雅,死亡現(xiàn)場(chǎng)離奇詭異裹粤,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)矮锈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)瀑凝,“玉大人猜丹,你說(shuō)我怎么就攤上這事÷龆伲” “怎么了艾疟?”我有些...
    開(kāi)封第一講書人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)怠苔。 經(jīng)常有香客問(wèn)我,道長(zhǎng)攒驰,這世上最難降的妖魔是什么玻粪? 我笑而不...
    開(kāi)封第一講書人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮晦鞋,結(jié)果婚禮上悠垛,老公的妹妹穿的比我還像新娘。我一直安慰自己湾趾,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著,像睡著了一般矢洲。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,146評(píng)論 1 297
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛陌知,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播掖肋,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼仆葡,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了志笼?” 一聲冷哼從身側(cè)響起沿盅,我...
    開(kāi)封第一講書人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎籽腕,沒(méi)想到半個(gè)月后嗡呼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡皇耗,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年南窗,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡万伤,死狀恐怖窒悔,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情敌买,我是刑警寧澤简珠,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站虹钮,受9級(jí)特大地震影響聋庵,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜芙粱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一祭玉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧春畔,春花似錦脱货、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至择份,卻和暖如春扣孟,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背荣赶。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工哈打, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人讯壶。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像湾盗,于是被迫代替她去往敵國(guó)和親伏蚊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理格粪,服務(wù)發(fā)現(xiàn)躏吊,斷路器,智...
    卡卡羅2017閱讀 134,651評(píng)論 18 139
  • pyspark.sql模塊 模塊上下文 Spark SQL和DataFrames的重要類: pyspark.sql...
    mpro閱讀 9,451評(píng)論 0 13
  • Lua 5.1 參考手冊(cè) by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 13,788評(píng)論 0 38
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法帐萎,類相關(guān)的語(yǔ)法比伏,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法疆导,異常的語(yǔ)法赁项,線程的語(yǔ)...
    子非魚_t_閱讀 31,622評(píng)論 18 399
  • 短暫的春節(jié)假期已經(jīng)迎來(lái)了尾聲,又回到了每天早起擠地鐵的生活,回到了忙碌而乏味的上班時(shí)光悠菜。過(guò)年仿佛一點(diǎn)痕跡都沒(méi)留下...
    清夢(mèng)無(wú)邊閱讀 226評(píng)論 0 0