Moq學習筆記

来源:http://www.cnblogs.com/Recoding/archive/2016/07/18/5680196.html
-Advertisement-
Play Games

什麼是Moq Moq是一個框架,一個可以模擬對象的框架,比如在不實現介面的情況下獲得介面的對象,這個介面的所有行為都可以用代碼控制 快速開始 被模擬的可以是介面和類,類不能是密封類,只有類中的虛函數能被模擬 先寫一個介面,下麵例子大部分用這個介面,但不全用這個介面 當不用 時候 Throws Moc ...


什麼是Moq

Moq是一個框架,一個可以模擬對象的框架,比如在不實現介面的情況下獲得介面的對象,這個介面的所有行為都可以用代碼控制

快速開始

被模擬的可以是介面和類,類不能是密封類,只有類中的虛函數能被模擬

先寫一個介面,下麵例子大部分用這個介面,但不全用這個介面

public interface IDemo
{
    int GetInt(int value);
    string GetString(string value);
    int Prop { get; set; }
}
//創建模擬對象
Mock<IDemo> mock = new Mock<IDemo>();
//開始設置這個對象的行為
//選擇要模擬的方法
mock.Setup(o => o.GetInt(It.IsAny<int>()))//設置給Get傳入任意int類型值時候才應用該行為
    .Returns<int>(o => o);//Func<int,int>第一個是傳入參數類型,第二個是返回數據類型,設置把傳入參數原樣返回
var obj = mock.Object;
var result=obj.GetInt(1);
Assert.AreEqual(1, result);

當不用It.IsAny<int>()時候

Mock<IDemo> mock = new Mock<IDemo>();
mock.Setup(o => o.GetInt(3))//設置給Get傳入3才應用該行為
    .Returns<int>(o => o);//Func<int,int>第一個是傳入參數類型,第二個是返回數據類型,設置把傳入參數原樣返回
var obj = mock.Object;
var result=obj.GetInt(1);//這裡不傳入3
Assert.AreEqual(1, result);//測試失敗,result實際為0

Throws

mock.Setup(o => o.GetInt(3))
    .Throws(new Exception("參數不能為空!"));

Mock

構造函數

public Mock();
public Mock(MockBehavior behavior);
public Mock(params object[] args);//arges,如果mock了一個類,可以為其構造函數傳入參數
public Mock(MockBehavior behavior, params object[] args);

MockBehavior

public enum MockBehavior
{
    //
    // 摘要:
    //     如果被調用方法沒被setup調用的時候回拋異常
    //     Causes the mock to always throw an exception for invocations that don't have
    //     a corresponding setup.
    Strict = 0,
    //
    // 摘要:
    //     絕不拋異常,必要時返回預設值(引用類型返回null,值類型返回0,空數組或枚舉器)
    //     Will never throw exceptions, returning default values when necessary (null for
    //     reference types, zero for value types or empty enumerables and arrays).
    Loose = 1,
    //
    // 摘要:
    //     預設值,效果與Loose一樣
    //     Default mock behavior, which equals Moq.MockBehavior.Loose.
    Default = 1
}

MockRespository

繼承MockFactory
故名思議一個工廠,這樣直接用工廠批量來創建對象,而不是一個個new

var factory = new MockRespository(MockBehavior.Strict);
//創建一個Mock
var aMock = factory.Create<IDemo>();
//等效於
var aMock=new Mock<IDemo>(MockBehavior.Strinct);

It

案例見文章開頭

方法 描述
Is<T>(Expression<Func<T, bool>> match) 指定參數必須符合match
IsAny<T>() 指定參數可以是任意值
IsRange<T>(min,max,kind) 指定參數需要在指定範圍內,kind可以是Inclusive或Exclusive
IsRegex(string regex) 指定傳入的字元串必須符合regex表示的正則

這些方法的返回值都是T類型,它就像一個過濾器,只有傳入參數符合條件才把它返回

Match

當上述的It不能滿足需求的時候就用Match

T Match.Create<T>(System.Predicate<T>)

//傳入字元串不能為空
mock.Setup(o => o.GetString(Match.Create<T>(o=>!o.IsNullOrEmpty())))

Verification

驗證某個方法是否被調用了或是否被調用XX次,若沒有則拋出異常
Verify

mock.Setup(o => o.GetInt(It.IsAny<int>()))
    .Returns<int>(o => o)
    .Verifiable();//設置可驗證的
mock.Verify();

拋出異常MockVerificationException,因為我設定了GetInt是要驗證的,但是我並沒有調用它,所以執行最後一行Verify時候拋出了異常
註意沒有設置的Verifiable的方法不會被檢查.



Verify()是Mock的方法,還有一些帶參數的Verify屬於Mock<T>

mock.Verify(o=>o.GetInt(1),Times.Once());

驗證GetInt方法以1為參數調用一次
Times.Once()是靜態方法,除了可以用Once還可以用 AtLeast, AtLeastOnce, AtMost, AtMostOnce, Between, Equals, Exactly, Never

Property

模擬屬性

mock.Setup(o => o.Prop).Returns(111);

這跟模擬方法差不多,因為屬性的本質就是方法

快速設置
屬性有種簡寫方式,只是單純地保存數據

public T PropertyName{ get; set;}

這個SetupProperty可以模擬這個行為

mock.SetupProperty(o => o.PropertyName,DefaultValue);


 Mock<IDemo> mock = new Mock<IDemo>();
 mock.SetupProperty(o => o.Prop);
 var obj = mock.Object;
 obj.Prop = 111;
 Console.WriteLine(obj.Prop);//輸出11
 
  Mock<IDemo> mock = new Mock<IDemo>();
 mock.SetupProperty(o => o.Prop,8888);
 var obj = mock.Object;
 Console.WriteLine(obj.Prop);//輸出8888

Callback

回調,故名思議但這個行為執行往後再執行的動作

  mock.Setup(o => o.GetInt(2))
                .Returns<int>(o => o)
                .Callback<int>(o => { Console.Write(o); });
                //當用模擬的對象調用GetInt且傳入參數為2的時候把參數2原樣返回
                //然後執行回調函數,把輸入參數輸出到控制台
 //不止一個地方能回調
 mock.Setup(o => o.GetInt(2))
              .Callback<int>(o => { Console.Write(o); });
              .Returns<int>(o => o)
              .Callback<int>(o => { Console.Write(o); });

Callback有多個重載

ICallbackResult Callback(Action action);
ICallbackResult Callback<T>(Action<T> action);
ICallbackResult Callback<T1, T2>(Action<T1, T2> action);
ICallbackResult Callback<T1, T2, T3>(Action<T1, T2, T3> action);
ICallbackResult Callback<T1, T2, T3, T4>(Action<T1, T2, T3, T4> action);
ICallbackResult Callback<T1, T2, T3, T4, T5>(Action<T1, T2, T3, T4, T5> action);
ICallbackResult Callback<T1, T2, T3, T4, T5, T6>(Action<T1, T2, T3, T4, T5, T6> action);
ICallbackResult Callback<T1, T2, T3, T4, T5, T6, T7>(Action<T1, T2, T3, T4, T5, T6, T7> action);
ICallbackResult Callback<T1, T2, T3, T4, T5, T6, T7, T8>(Action<T1, T2, T3, T4, T5, T6, T7, T8> action);
ICallbackResult Callback<T1, T2, T3, T4, T5, T6, T7, T8, T9>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9> action);
ICallbackResult Callback<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> action);
ICallbackResult Callback<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> action);
ICallbackResult Callback<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> action);
ICallbackResult Callback<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> action);
ICallbackResult Callback<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> action);
ICallbackResult Callback<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> action);
ICallbackResult Callback<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(Action<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> action);

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 快捷鍵是Ctrl+F8 快捷鍵是Ctrl+Shift +Alt +A ...
  • 作為一個菜鳥,避免不了被老鳥罵爹,但是如果能有一手漂亮的代碼給你作盾牌,多少能擋掉不少的鋒芒,作為菜鳥中的菜鳥的我,便嘗試起了重構自己的代碼。 這是一種不堪的憂傷…… 首先,教材入手《重構:改善即有代碼的設計》,重點是PDF版本,又是憂傷,買本書都沒錢了,又是一種憂傷…… 然後就對著書,邊學習,便嘗... ...
  • 在我們前面的代碼中已經接觸到了C#的類(class)還有類的方法。我們的代碼主要都放在Program 類的Main方法裡邊。我們也創建了我們自己的方法。同時我們也使用了類Console的writeline等方法。但是我想到目前為止我們還是不是很清楚類是一個什麼東西。接下來我就給大家介紹一下類還有面向 ...
  • 在離線環境中使用.NET Core 0x00 寫在開始 很早開始就對.NET Core比較關註,一改微軟之前給人的印象,變得輕量、開源、跨平臺。最近打算試著在工作中使用。但工作是在與互聯網完全隔離的網路中進行的,因此就開始了在離線環境中部署.NET Core開發環境的嘗試。總的來說還是比較蛋疼的,幾 ...
  • 分頁和排序,應該是軟體開發中,需要必知必會的技能了,對於分頁,網上很多教程,當然,別人終究是別人的,只有自己理解,會了,並且吸收之後,再用自己的語言,傳授出來,這才是硬道理。好了,廢話說多了。現在我們進入正題: 這裡,我打算使用EF Code-First方式分頁控制項就是用PagedList.MVC, ...
  • 隨著V5框架使用者的快速增加,終於促使我開始對整個框架編寫完整的Demo。上周大概花了一星期的時間,每天寫到夜裡3點半,終完成了框架所有功能的Demo。同時,按V5框架名稱空間的順序,對每個類的使用,補充相應的文章介紹,以漏補缺。 ...
  • 昨天《怎樣操作WebAPI介面(顯示數據)》http://www.cnblogs.com/insus/p/5670401.html既有使用jQuery,也有使作HttpClient來從資料庫獲取數據,並顯示在ASP.NET MVC的視圖中。今天Insus.NET想把例子全完成,就是把其餘的添加,更新 ...
  • 最近跟著師父學習軟體,因為軟體比較複雜,所以設計到判斷某個窗體是否打開了,如果打開了,進行某種操作,如果沒有打開,又進行另一種操作。 雖然不難,但是記一下總是好的。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...