2013-05-09 22 views
1

目前,我使用的是在幕後用NSubstitute它創建實際的對象,但它變得非常難以維護定製的虛假對象隨着項目的發展,我正在努力尋找替代方案,我希望AutoFixture是這項工作的正確工具。新來AutoFixture試圖讓我的頭周圍,我無法看到它幫助我

我閱讀文檔,我掙扎,因爲有很少沒有文檔和我讀書最多的博客文章由馬克·西曼包括的cheatsheet的。

我很難掌握的一件事是如何使用帶參數的構造函數創建對象,在我的情況下,我需要將參數傳遞給CsEmbeddedRazorViewEngine以及將HttpRequestBase傳遞給ControllerContext。

我看到的是,我需要創建一個假的對象,並最終創建一個將它們注射到

我也看了成NBuilder定製對象似乎略多瑣碎來傳遞參數有,但我一直的方式聽說過有關AutoFixture的好消息,我想試試看。 :)

我想,以減少虛假對象我有那麼這裏是一個真正的考驗的量,我該怎麼做AutoFixture同樣的事情?

[Theory, 
InlineData("en-US"), 
InlineData("en-us"), 
InlineData("en")] 
public void Should_return_the_default_path_of_the_view_for_enUS(string language) 
{ 
    // Arrange 
    const string EXPECTED_VIEW_PATH = "~/MyAssemblyName/Views/Home/Index.cshtml"; 

    CsEmbeddedRazorViewEngine engine = CsEmbeddedRazorViewEngineFactory.Create(ASSEMBLY_NAME, VIEW_PATH, string.Empty); 

    string[] userLanguage = { language }; 

    HttpRequestBase request = FakeHttpRequestFactory.Create(userLanguage); 

    ControllerContext controllerContext = FakeControllerContextFactory.Create(request); 

    // Act 
    ViewEngineResult result = engine.FindPartialView(controllerContext, VIEW_NAME, false); 

    // Assert 
    RazorView razorView = (RazorView)result.View; 

    string actualViewPath = razorView.ViewPath; 

    actualViewPath.Should().Be(EXPECTED_VIEW_PATH); 
} 

P.S.我使用xUnit作爲我的測試框架,NSubstitute作爲我的模擬框架,我應該安裝AutoFixture.Xunit和AutoFixture.AutoNSubstitute?

UPDATE:瞭解它越來越多後,我想這是不是爲工作的工具,因爲我試圖取代我的測試與AutoFixture雙打工廠,而不是設置了我的SUT它。

由於奇怪的原因,我想它做NBuilder正在做同樣的事情,從我所看到的,他們是非常不同的工具。

因此,經過一番思考,我想我會去改變我的測試方法,使工廠將對象加倍,然後使用AutoFixture創建我的SUT並將測試雙擊插入到對象中。

回答

4

注意:我沒有CsEmbeddedRazorViewEngine類型和所有其他自定義類型的源代碼。

這裏是如何可能與AutoFixture寫:

[Theory] 
[InlineAutoWebData("en-US", "about", "~/MyAssemblyName/Views/Home/Index.cshtml")] 
[InlineAutoWebData("en-US", "other", "~/MyAssemblyName/Views/Home/Index.cshtml")] 
public void Should_return_the_default_path_of_the_view_for_enUS(
    string language, 
    string viewName, 
    string expected, 
    ControllerContext controllerContext, 
    CsEmbeddedRazorViewEngine sut) 
{ 
    var result = sut.FindPartialView(controllerContext, viewName, false); 
    var actual = ((RazorView)result.View).ViewPath; 

    actual.Should().Be(expected); 
} 

它是如何工作

它採用AutoFixture本身連同它的膠水庫xUnit.net和NSubstitute:

PM> Install-Package AutoFixture.Xunit 
PM> Install-Package AutoFixture.AutoNSubstitute 

隨着InlineAutoWebData你實際上通過AutoFixture結合了內聯值和自動生成的數據值 - 還包括NSubstitute的自動模擬。

internal class InlineAutoWebDataAttribute : CompositeDataAttribute 
{ 
    internal InlineAutoWebDataAttribute(params object[] values) 
     : base(
      new InlineDataAttribute(values), 
      new CompositeDataAttribute(
       new AutoDataAttribute(
        new Fixture().Customize(
         new WebModelCustomization())))) 
    { 
    } 
} 

備註

其實你可以更換WebModelCustomization定製以上AutoNSubstituteCustomization和它可以工作。

但是,假設你正在使用ASP.NET MVC 4,你需要定製Fixture實例:

internal class WebModelCustomization : CompositeCustomization 
{ 
    internal WebModelCustomization() 
     : base(
      new MvcCustomization(), 
      new AutoNSubstituteCustomization()) 
    { 
    } 

    private class MvcCustomization : ICustomization 
    { 
     public void Customize(IFixture fixture) 
     { 
      fixture.Customize<ControllerContext>(c => c 
       .Without(x => x.DisplayMode)); 

      // Customize the CsEmbeddedRazorViewEngine type here. 
     } 
    } 
} 

進一步閱讀

+0

哇!非常感謝你,我會嘗試。 – 2013-05-09 08:51:20

+0

不客氣!請注意,我不希望測試通過,因爲您將必須使用自定義類型來完成'MvcCustomization'。另請注意,單元測試ASP.NET MVC 4很難.. – 2013-05-09 08:55:17

+0

是的,我只是試圖運行它哈哈......在我開始使用它之前,我將不得不詳細閱讀它,因爲似乎有很多東西需要了解這個特定的庫。 – 2013-05-09 09:03:10

0

我最終這樣做了。

[Theory, 
InlineData("en-US", "Index", "~/MyAssemblyName/Views/Home/Index.cshtml"), 
InlineData("en-us", "Index", "~/MyAssemblyName/Views/Home/Index.cshtml"), 
InlineData("en", "Index", "~/MyAssemblyName/Views/Home/Index.cshtml")] 
public void Should_return_the_default_path_of_the_view(string language, string viewName, string expected) 
{ 
    // Arrange 
    CsEmbeddedRazorViewEngine engine = new CsEmbeddedRazorViewEngineFixture(); 

    ControllerContext controllerContext = FakeControllerContextBuilder.WithLanguage(language).Build(); 

    // Act 
    ViewEngineResult result = engine.FindPartialView(controllerContext, viewName, false); 

    // Assert 
    string actualViewPath = ((RazorView)result.View).ViewPath; 

    actualViewPath.Should().Be(expected); 
} 

我封裝的細節設置我的SUT到夾具和使用生成器模式來處理我的假貨,我認爲現在是可讀的,非常簡單。

雖然AutoFixture看起來很酷,但學習曲線看起來很長,我需要投入足夠的時間來理解它,現在我想清理單元測試並使它們更具可讀性。 :)

相關問題