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

首頁 > 編程 > .NET > 正文

moq 的常用使用方法(推薦)

2024-07-10 13:31:31
字體:
來源:轉載
供稿:網友

Moq,就是Mock you。讀音可以讀成Mock~you。是Mock框架的一種。用于測試中的Mock測試。Mock是模擬的意思。Mock是模擬對象的一種技術。

測試方法

// 準備 Mock IFoo 接口var mock = new Mock<IFoo>(); // 配置準備模擬的方法,當調用接口中的 DoSomething 方法,并傳遞參數 "bing" 的時候,返回 truemock.Setup(foo => foo.DoSomething("ping")).Returns(true); // 方法的參數中使用了 out 參數// out arguments var outString = "ack"; // 當調用 TryParse 方法的時候,out 參數返回 "ack", 方法返回 true, lazy evaluated mock.Setup(foo => foo.TryParse("ping", out outString)).Returns(true); // ref 參數var instance = new Bar(); // 僅僅在使用 ref 調用的時候,才會匹配下面的測試mock.Setup(foo => foo.Submit(ref instance)).Returns(true); // 當方法返回值得時候,還可以訪問返回的值// 這里可以使用多個參數mock.Setup(x => x.DoSomething(It.IsAny<string>())).Returns((string s) => s.ToLower()); // 在被調用的時候拋出異常mock.Setup(foo => foo.DoSomething("reset")).Throws<InvalidOperationException>(); mock.Setup(foo => foo.DoSomething("")).Throws(new ArgumentException("command"); // 延遲計算返回的結果 mock.Setup(foo => foo.GetCount()).Returns(() => count); // 在每一次調用的時候,返回不同的值 var mock = new Mock<IFoo>(); var calls = 0; mock.Setup(foo => foo.GetCountThing()).Returns(() => calls).Callback(() => calls++); // 第一次調用返回 0, 下一次是 1, 依次類推Console.WriteLine(mock.Object.GetCountThing());

匹配參數

// 任意值 mock.Setup(foo => foo.DoSomething(It.IsAny<string>())).Returns(true); // 提供的值必須匹配一個函數, lazy evaluated mock.Setup(foo => foo.Add(It.Is<int>(i => i % 2 == 0))).Returns(true); // 匹配一個范圍 mock.Setup(foo => foo.Add(It.IsInRange<int>(0, 10, Range.Inclusive))).Returns(true); // 匹配正則表達式mock.Setup(x => x.DoSomething(It.IsRegex("[a-d]+", RegexOptions.IgnoreCase))).Returns("foo");

屬性

// 普通屬性mock.Setup(foo => foo.Name).Returns("bar"); // 多層的屬性mock.Setup(foo => foo.Bar.Baz.Name).Returns("baz"); // 期望設置屬性的值為 "foo" mock.SetupSet(foo => foo.Name = "foo"); // 或者直接驗證賦值 mock.VerifySet(foo => foo.Name = "foo");

設置屬性,以便自動跟蹤它的值

// 開始 "tracking" 屬性的 sets/gets mock.SetupProperty(f => f.Name); // 提供一個默認的值mock.SetupProperty(f => f.Name, "foo"); // 現在,你可以: IFoo foo = mock.Object; // 保存的值 Assert.Equal("foo", foo.Name); // 重新設置一個值foo.Name = "bar"; Assert.Equal("bar", foo.Name);

還可以準備所有的屬性

mock.SetupAllProperties();

事件

// 拋出一個事件 mock.Raise(m => m.FooEvent += null, new FooEventArgs(fooValue)); // 多層的后代中的事件 mock.Raise(m => m.Child.First.FooEvent += null, new FooEventArgs(fooValue)); // 當 Submit 方法被調用的時候,拋出一個事件 mock.Setup(foo => foo.Submit()).Raises(f => f.Sent += null, EventArgs.Empty); // 拋出異常將會觸發對象底層的行為// 你可能需要在后面進行斷言處理// 拋出一個自定義的事件public delegate void MyEventHandler(int i, bool b); public interface IFoo { event MyEventHandler MyEvent; } var mock = new Mock<IFoo>(); ... // 傳遞自定義的事件參數mock.Raise(foo => foo.MyEvent += null, 25, true);

回調

var mock = new Mock<IFoo>(); mock.Setup(foo => foo.Execute("ping")).Returns(true).Callback(() => calls++); // 使用調用的參數 mock.Setup(foo => foo.Execute(It.IsAny<string>())).Returns(true).Callback((string s) => calls.Add(s)); // 使用泛型語法 mock.Setup(foo => foo.Execute(It.IsAny<string>())).Returns(true).Callback<string>(s => calls.Add(s)); // 使用多個參數mock.Setup(foo => foo.Execute(It.IsAny<int>(), It.IsAny<string>())).Returns(true).Callback<int, string>((i, s) => calls.Add(s)); // 調用之前和之后的回調 mock.Setup(foo => foo.Execute("ping")).Callback(() => Console.WriteLine("Before returns")).Returns(true).Callback(() => Console.WriteLine("After returns"));

驗證

mock.Verify(foo => foo.Execute("ping")); // 在驗證失敗的時候,提供自定義的錯誤提示信息 mock.Verify(foo => foo.Execute("ping"), "When doing operation X, the service should be pinged always"); // 從沒有被調用的方法 mock.Verify(foo => foo.Execute("ping"), Times.Never()); // 至少調用過一次 mock.Verify(foo => foo.Execute("ping"), Times.AtLeastOnce()); mock.VerifyGet(foo => foo.Name); // 驗證對屬性的賦值. mock.VerifySet(foo => foo.Name); // 驗證對于屬性設置特定的值 mock.VerifySet(foo => foo.Name ="foo"); // 驗證匹配的參數 mock.VerifySet(foo => foo.Value = It.IsInRange(1, 5, Range.Inclusive));

自定義 Mock 行為

Mock 的行為分為嚴格的 Strict 和寬松的 Loose, 默認為寬松的。在嚴格模式下,使用任何沒有被指定的行為,都將會拋出異常,寬松模式下,不會拋出任何異常,方法將會返回默認值或者空的數組等等。

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

如果沒有重寫基類的實現,默認將不會調用基類,在 Mock Web/Html 控件的是必須的。

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

創造自動遞歸的 Mock, Mock 對象對于它的任何成員將會返回一個新的 Mock 對象。

var mock = new Mock<IFoo> { DefaultValue = DefaultValue.Mock }; // 默認是 DefaultValue.Empty // 現在這個屬性將會返回一個新的 Mock 對象 IBar value = mock.Object.Bar; // 可以使用返回的 Mock 對象, 后即對屬性的訪問返回相同的對象實例// 這就允許我們可以進行后繼的設置 // set further expectations on it if we want var barMock = Mock.Get(value); barMock.Setup(b => b.Submit()).Returns(true);

中心化的 Mock 實例創建和管理:你可以在一個地方使用 MockRepository 創建和驗證所有的 Mock 對象,設置 MockBehavior, CallBse 和 DefaultValue 約束。

var factory = new MockFactory(MockBehavior.Strict) { DefaultValue = DefaultValue.Mock }; // 創建 Mock 對象var fooMock = factory.Create<IFoo>(); // 在創建的時候重寫倉庫的設置 var barMock = factory.Create<IBar>(MockBehavior.Loose); // 驗證通過倉庫創建的對象 factory.Verify();

其它

// 用在測試用例的開始 using Moq.Protected() // 測試中var mock = new Mock<CommandBase>(); mock.Protected().Setup<int>("Execute").Returns(5); // 如果用到了參數匹配, 必須使用 ItExpr 來代替 It // 以后計劃改進mock.Protected().Setup<string>("Execute", ItExpr.IsAny<string>()).Returns(true);

高級特性

// 從 Mock 實例重新獲得 Mock 對象IFoo foo = // get mock instance somehow var fooMock = Mock.Get(foo); fooMock.Setup(f => f.Submit()).Returns(true); // 實現多個接口 var foo = new Mock<IFoo>(); var disposableFoo = foo.As<IDisposable>(); // 現在 IFoo mock 已經實現了接口 IDisposable :) disposableFoo.Setup(df => df.Dispose()); // 定制匹配 mock.Setup(foo => foo.Submit(IsLarge())).Throws<ArgumentException>(); ... public string IsLarge() {return Match<string>.Create(s => !String.IsNullOrEmpty(s) && s.Length > 100); }

以上所述是小編給大家介紹的moq 的常用使用方法,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對VeVb武林網網站的支持!

 

注:相關教程知識閱讀請移步到ASP.NET教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产精品 欧美在线| 欧美天天综合色影久久精品| 欧美最顶级的aⅴ艳星| 欧美综合一区第一页| 91chinesevideo永久地址| 91av视频在线| 成人黄色大片在线免费观看| 国产精品日韩在线一区| 亚洲国产成人av在线| 欧美一区二区三区精品电影| 久久久久久噜噜噜久久久精品| 俺去亚洲欧洲欧美日韩| 日韩精品www| 538国产精品一区二区在线| 欧美成人午夜视频| 欧美日韩另类视频| 538国产精品视频一区二区| 国产精品久久久久久久久久久久久久| 国产精品wwww| 欧美中文字幕精品| 亚洲欧美另类人妖| 日韩有码在线电影| 欧美自拍视频在线观看| 精品久久久久久久久久久| 欧美做爰性生交视频| 亚洲一区二区三区四区在线播放| 亚洲福利视频久久| 亚洲国产又黄又爽女人高潮的| 精品国产鲁一鲁一区二区张丽| 亚洲国产精品一区二区久| 久久精品影视伊人网| 国产精品r级在线| 欧美日韩成人在线视频| 亚洲jizzjizz日本少妇| 2020欧美日韩在线视频| 久久综合免费视频影院| www.久久久久久.com| 成人午夜黄色影院| 日韩欧美一区二区三区| 国产在线a不卡| 少妇高潮久久77777| 国产精品自产拍在线观| 欧洲永久精品大片ww免费漫画| 中文字幕精品一区二区精品| 国产精品女人久久久久久| 亚洲国产欧美一区| 色婷婷久久一区二区| 国产免费一区二区三区在线能观看| 亚洲欧美国产va在线影院| 久久躁狠狠躁夜夜爽| 欧美电影免费观看| 亚洲一区二区福利| 91视频免费在线| 国产精品v片在线观看不卡| 91夜夜未满十八勿入爽爽影院| 欧美激情免费观看| 中文字幕欧美专区| 国产视频在线一区二区| www.欧美免费| 国产成人aa精品一区在线播放| 亚洲精品视频中文字幕| 精品国模在线视频| 欧美激情2020午夜免费观看| 国产精品视频网| 福利视频导航一区| 国产精品手机播放| 欧美成人国产va精品日本一级| 黑人狂躁日本妞一区二区三区| 欧美激情女人20p| 91精品中国老女人| 亚洲精品视频在线播放| 久久久国产在线视频| 91国产中文字幕| 18一19gay欧美视频网站| 91麻豆国产语对白在线观看| 欧美一级淫片videoshd| 尤物精品国产第一福利三区| 国产精品99久久久久久久久久久久| 成人黄色av网| 亚洲精品网站在线播放gif| 精品一区二区三区四区在线| 性欧美长视频免费观看不卡| 91久久精品国产| 国产精品成熟老女人| 另类美女黄大片| 欧美激情按摩在线| 久久精品国产亚洲7777| 久久国产精品免费视频| 国产精品久久久av| 国产精品久久一区| 欧美性20hd另类| 国产精品久久久久久久久粉嫩av| 欧美影院久久久| 欧美老少做受xxxx高潮| 国产精品网站大全| 欧美日韩福利在线观看| 美女撒尿一区二区三区| 欧美夫妻性生活xx| 自拍偷拍亚洲欧美| 日本三级韩国三级久久| 大桥未久av一区二区三区| 色爱精品视频一区| 久久久久久中文| 91久久精品在线| 一区二区成人精品| 欧美另类交人妖| 午夜精品在线视频| 国产免费一区二区三区香蕉精| 久久久久久久久久婷婷| 亚洲精美色品网站| 亚洲免费电影在线观看| 亚洲免费成人av电影| 国产成人av在线| 国产精品美女主播| 2019中文字幕免费视频| 国产mv久久久| 久久91精品国产91久久跳| 亚洲福利影片在线| 亚洲二区在线播放视频| 国产精品自产拍在线观| 国模吧一区二区三区| 欧美性xxxxxx| 精品亚洲精品福利线在观看| 欧美专区国产专区| 国产视频亚洲视频| 91精品国产91久久久久久最新| 欧美日韩国产精品专区| 亚洲一区中文字幕| 91色视频在线观看| 欧美亚洲成人精品| 国语自产偷拍精品视频偷| 国产噜噜噜噜噜久久久久久久久| 久久韩剧网电视剧| 亚洲精品aⅴ中文字幕乱码| 欧美日韩国产丝袜美女| 成人在线小视频| 国产精品美女久久久久久免费| 国产精品国产三级国产专播精品人| 色婷婷久久av| 国产精品久久久久久久久久ktv| 亚洲国产古装精品网站| 精品国产福利视频| 日本韩国在线不卡| 国产色婷婷国产综合在线理论片a| 色视频www在线播放国产成人| 久久久免费在线观看| 日韩免费av一区二区| 日韩av在线免费看| 欧美极品在线播放| 国模gogo一区二区大胆私拍| 九九精品在线视频| 亚洲性无码av在线| 777午夜精品福利在线观看| 午夜精品免费视频| 久久久欧美精品| 国产精品一区二区三区久久久| 国产精品久久久久影院日本| 欧亚精品在线观看| 日韩视频一区在线| 欧美日韩国产影院| 91在线无精精品一区二区| 91最新在线免费观看| 日韩视频免费在线观看| 欧美日韩成人在线观看|