<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      samesite


      【ASP.Net MVC3 】使用Moq讓單元測試變得更簡單

      前幾天調查完了unity?,F在給我的任務是讓我調查Moq。

      以下是自己找了資料,總結并實踐的內容。如果有表述和理解錯誤的地方。懇請指正。

      什么是Moq?

       

      Moq(英語發音是Mock-you 或者只是mock)是一個針對.Net開發的模擬庫,它從開始就完全充分利用了.NET3.5(LINQ表達式樹)和C#3.0的新特性(lambda表達式)。它的目標是讓模擬以一種自然的方式與現有單元測試進行集成,使它更加簡單、直觀,以避免開發人員被迫重寫測試或高成本的學習測試框架。這使它成為了一個高生產力、類型安全、重構友好的模擬庫。

      從哪得到Moq?

       

      如果你看過我的其他文章,我們可以直接使用 VS中的插件Nuget來獲取Moq并且引用到指定的項目。

      否則,我們可以從http://code.google.com/p/moq/這里得到Moq的最新版本。

      可以模擬什么?局限性

       

      首先,模擬的類不能是密封的。

      其次,你不能直接模擬靜態方法。因為Moq只能創建模擬對象實例。在這種情況下,間接的解決方案是我們可以在要模擬對象外包裝一層,并且去模擬這個新對象。這種模式被稱為適配器模式。

      通常我們測試一個方法,它有可能調用好幾個service。但是每次都去訪問這些service的代價是很高的。我們可以通過模擬的方法讓它模擬訪問service,并且根據不同請求模擬返回響應的結果。

      Moq原理

       

      Moq是如何辦到的?它只需要一個接口類型就可以生產一個對象?沒錯,就是這樣。Moq使用 Castle DynamicProxy 完成這個任務?;驹砭褪撬梅瓷錂C制的 Emit 功能動態生成一個空類型(也就是所有接口的方法都實例化,但是沒有任何功能,只是一個程序骨架)。所以Mock的能力就在于可以利用DynamicProxy的機制快速生產出一個假對象來,用于模仿真對象的行為。

       

      Moq中的重要成員

       

      Mock

      通過這個類,我們可以得到一個Mock<T>對象。T可以是接口,也可以是類。它有一個public 和virtual屬性。讓我們看看下邊的例子:

              //define interface to be mocked

      public interface IFake
      {

      bool DoSomething(string actionname);

      }

      //define the test method

      [TestMethod]

      public void Test_Interface_IFake()
      {

      //make a mock Object by Moq

      var mo = new Mock<IFake>();

      //Setup our mock object

      mo.Setup(foo => foo.DoSomething("Ping"))

      .Returns(true);

      //Assert it!

      Assert.AreEqual(true, mo.Object.DoSomething("Ping"));
      }

      在上邊的代碼,我們通過傳遞泛型參數IFake去創建Mock<IFake>的實例 模擬接口IFake。

      接下來我們要調用Setup()方法去創建我們的模擬對象。注意,Setup方法的參數是一個lambda表達式。我們可以這樣理解:當被模擬的對象foo調用它自己的方法DoSomething(),并且參數是Ping。添加后綴 Return (true)我們可以理解為:前邊的請求返回結果為真。這是我們指定的返回值。當一個請求調用DoSomething()方法時。如果傳入的參數是Ping,那么我們會返回true。接下來,我們添加一個斷言,去判斷是否能得到預期結果。

      注:Foo僅僅是一個詞用作通用替代真實的東西,特別是在討論技術想法和問題.

      It

       

      這是一個靜態類,定義了靜態的泛型方法:Is<TValue>, IsAny<TValue>, IsInRange<TValue>, 和IsRegex。去過濾參數。看看下邊例子:

      public interface IEmailSender
      {

      bool Send(string subject, string body, string email);

      }
      [TestMethod]

      public void User_Can_Send_Password()
      {

      var emailMock = new Mock<IEmailSender>();

      emailMock

      .Setup(sender => sender.Send(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>()))

      .Returns(true);

      }

      任何時候調用Send()方法,只要傳入的參數是任何的string,我們定義他會返回true。

      我們也可以根據lambda的優勢訂制一個規則:

                

        var productRepository = new Mock<IProductRepository>();

      productRepository

      .Expect(p => p.Get(It.Is<int>(id => id > 0 && id < 6)))

      .Returns(newProduct.Object);

       

      這樣我們可以設置這個id在0和6之間的時候才會返回一個新的對象。上邊提及到的其他方法,我們可以參考這里的教程 Moq’s QuickStart

      此外,這個類的增強版是 Match<T>,你完全可以自定義模擬規則。

      MockBehavior

       

      這個類用于模擬對象的行為。就像是否按照默認的模式去模擬。讓我們進一步看看他的定義:

      namespace Moq
      {
      // Summary:
      // Options to customize the behavior of the mock.
      public enum MockBehavior
      {
      // Summary:
      // Causes the mock to always throw an exception for invocations that don't have
      // a corresponding setup.
      Strict = 0,
      //
      // Summary:
      // Will never throw exceptions, returning default values when necessary (null
      // for reference types, zero for value types or empty enumerables and arrays).
      Loose = 1,
      //
      // Summary:
      // Default mock behavior, which equals Moq.MockBehavior.Loose.
      Default = 1,
      }
      }

       

      現在,看看如下例子:

       

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

      指定了mock行為是精準的,如果沒有按照預期的Setup就會拋出異常。

      MockFactory

       

      這是一個模擬對象的工廠,我們不僅僅可以定制創建模擬對象的配置,也可以成批測試它們??纯聪逻吚樱?/p>

       

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

      // Create a mock using the factory settings

      var fooMock = factory.Create<IFake>();

      // Create a mock overriding the factory settings

      var barMock = factory.Create<IEmailSender>(MockBehavior.Loose);

      // Verify all verifiable expectations on all mocks created through the factory

      factory.Verify();

      在前邊,我們已經介紹了傳統方式的創建模擬對象,它不會去真正的調用方法,而是僅僅去執行一些假設:如果...那么返回... 。

      在下邊的例子里,我將繼續介紹一些Mock<T> 類中基本并且重要的方法。

      Verification

       

      有時候,我們要確定一個方法是否被調用了,或者甚至要知道它被調用了多少次。一個比較傳統的方式是使用Verify()方法??纯聪逻吚樱?/p>

      mock.Verify(foo => foo.DoSomething("Ping"), Times.Once());

      上邊的代碼嘗試驗證DoSomething("Ping")需要被調用,并且只調用一次。出了Once選項,這里也有更多的選項可供你選擇去決定這個方法需要被調用多少次。如: AtLeast, AtLeastOnce, AtMost, AtMostOnce, Between, Equals, Exactly, Never, 和Once

      一旦我們已經模擬了對象,驗證將是個輕松的任務,看看下邊的例子:

         [TestMethod]

      public void Test_FindByName_GetCalled()
      {

      // create some mock data

      IList<Product> products = new List<Product>

      {

      new Product { ProductId = 1, Name = "C# Unleashed",

      Description = "Short description here", Price = 49.99 },

      new Product { ProductId = 2, Name = "ASP.Net Unleashed",

      Description = "Short description here", Price = 59.99 },

      new Product { ProductId = 3, Name = "Silverlight Unleashed",

      Description = "Short description here", Price = 29.99 }

      };

      Mock<IProductRepository> mock = new Mock<IProductRepository>();

      //mock

      //.Setup(sender => sender.FindById(It.IsAny<int>()))

      //.Returns((int s) => products.Where(

      // x => x.ProductId == s).Single());

      mock.Object.FindById(1);

      mock

      .Verify(x => x.FindById(1), Times.Once());

      }
      }

      在上邊的例子里,有兩個地方值得注意。

      首先是mock.Object.FindById(1)。為了在這個case里讓一切變得簡單,我們直接調用mock.Object的方法。為什么呢?因為我們這個case只關注這個方法被調用的次數,而不關注返回值。當然,在實際的應用中我們很少這樣做。

      第二,你有沒有注意到被注釋掉的句子。它僅僅是一個“如果,那么”句子。意思是說,如果Setup 好了,就返回我們定義的值。

      由于調查的時間有限,還有很多關于Mock給力的地方我沒有涉及到。我們可以去查看官方的資料。歡迎共同討論。

       

       

      參考資料

      http://stephenwalther.com/blog/archive/2008/06/12/tdd-introduction-to-moq.aspx

      http://blog.miniasp.com/post/2010/09/16/ASPNET-MVC-Unit-Testing-Part-03-Using-Mock-moq.aspx
      http://dotnetslackers.com/articles/aspnet/Built-in-Unit-Test-for-ASP-NET-MVC-3-in-Visual-Studio-2010-Part-2.aspx#s4-using-moq-framework



      posted @ 2012-01-10 12:54  技術弟弟  閱讀(19518)  評論(30)    收藏  舉報
      主站蜘蛛池模板: 欧美黑人粗暴多交高潮水最多 | 99久久无码一区人妻a黑| 色综合AV综合无码综合网站| 男人猛躁进女人免费播放| 欧美一区二区三区在线观看| 车险| 国产av一区二区麻豆熟女| 国产精品 欧美 亚洲 制服| 宁晋县| 亚洲人成人伊人成综合网无码| 国产制服丝袜无码视频| 久久国产免费观看精品3| 国产成人一区二区三区在线| 波多野结衣久久一区二区| 亚洲精品一区二区制服| 久久人人97超碰精品| 亚洲国产成人久久一区久久 | 孕妇特级毛片ww无码内射| 亚洲欧美v国产蜜芽tv| 成人国产av精品免费网| 国产在线乱子伦一区二区| 亚洲AVAV天堂AV在线网阿V| 亚洲自拍精品视频在线| 亚洲Av综合日韩精品久久久| 日本一区二区三区在线播放| 色狠狠色噜噜AV一区| 东京热加勒比无码少妇| 国产精品久久久久久影视| 日本污视频在线观看| 性色av极品无码专区亚洲| 亚洲国产精品一区二区第一页| 亚洲国产欧美一区二区好看电影 | 麻豆人妻| 亚洲中文久久久精品无码| 国产亚洲精品第一综合麻豆| 夜夜添无码一区二区三区| 国产人妻精品午夜福利免费| 亚洲天堂激情av在线| 日韩一区二区a片免费观看| 亚洲国产片一区二区三区| 久久五月丁香激情综合|