2015-04-23 63 views
3

我一直在使用起訂量了一段時間,並且爲了簡潔我往往比使用Mock.Of流利的語法不表達設置...AutoFixture流暢的起訂量語法

var foo = Mock.Of<IFoo>(f => f.Method(It.IsAny<string>()) == 7 && f.Property == "Hi"); 
var sut = new Whatever(foo); 

最近,我已經開始玩弄AutoFixture,似乎無法找到任何同時表達多個設置的等效語法。我明白,我可以表達使用Freeze同樣的事情...

var foo = fixture.Freeze<Mock<IFoo>>(); 
foo.Setup(f => f.Method(It.IsAny<string>()).Returns(7); 
foo.Setup(f => f.Property).Returns("Hi"); 
var sut = fixture.Create<Whatever>(); 

...但如果可能的話,我想獲得automocking的好處,並保持流暢的起訂量設置的簡潔。除了文體學的觀點外,AutoFixture能讓我更流暢地表達這些設置嗎?如果沒有,我可以使用哪些優化使AutoFixture設置更簡潔?

+2

你有沒有考慮使用NSubstitute?這是OOTB *顯着*清潔比Moq(也有一個AutoNSubstitute膠庫),所以如果你沒有顯着的不可忽略的沉沒成本,你沒有任何損失,但括號:) –

+2

@RubenBartelink,在這種情況下,特別我正在與在企業環境中基於10k + Moq/NUnit的測試,所以框架轉換可能不太可能。然而,對於我的個人項目,我肯定會看看它(我可以在網上找到的幾個比較非常有人氣,並將NSubstitute與非流利的Moq語法進行比較,這非常「羅嗦」,所以我必須做一個一點研究和嘗試自己)。 – ScheuNZ

+0

在這種情況下具有完美意義:P –

回答

4

你可以創建一個使用起訂量的流暢API的嘲笑自己,然後注入其放回夾具:

var foo = Mock.Of<IFoo>(f => f.Method(It.IsAny<string>()) == 7 && f.Property == "Hi"); 
fixture.Inject(foo); 

var sut = fixture.Create<Whatever>(); 

如果您正在使用AutoMoqCustomization,那麼上面的代碼會做同樣的事情您發佈的代碼除了未設置CallBase = trueDefaultValue = DefaultValue.Mock;

如果您使用AutoConfiguredMoqCustomization,那麼此代碼將不會設置任何其他成員,而定製會。如果您想要獲得AutoConfiguredMoqCustomization的好處,請使用Moq流暢的API,恐怕這是不可能的。

+0

不錯。如果你在我的答案中包含幫助者和/或合併,我會刪除我的,因爲碰到的關鍵是自動配置按照你所說的那樣用「Inject」敲掉。 –

+2

@RubenBartelink我不想偷你的信用,讓我們保留這兩個答案;) – dcastro

+0

@dcastro,謝謝 - 這回答我的問題。我希望它可以直接烘焙到'Freeze'或其他方法中,這樣我就可以減少另外一個'Mock.Of '引入的噪音。我已經使用過輔助方法(擴展和實例)來清理它,所以你的答案和Ruben的幫助器方法就足夠了。我正在使用'AutoMoqCustomization',所以'Inject'的使用不應該是一個問題。再次感謝。 – ScheuNZ

4

Riffing上@ dcastro的回答,小包裝這將具有相同的警告所涵蓋有: -

public static T SetMock<T>(this IFixture that, Expression<Func<T, bool>> expr) 
    where T : class 
{ 
    var mocked = Mock.Of(expr); 
    that.Inject(mocked); 
    return mocked; 
} 

允許您:

fixture.SetMock<IFoo>(f => 
    f.Method(It.IsAny<string>()) == 7 
    && f.Property == "Hi"); 

或者,當且僅當你有興趣具體值:

var foo = fixture.SetMock<IFoo>(f => 
    f.Method(It.IsAny<string>()) == 7 
    && f.Property == "Hi"); 

最乾淨的C#,沒有幫手是:

fixture.Inject(Mock.Of<IFoo>(f => 
    f.Method(It.IsAny<string>()) == 7 
    && f.Property == "Hi"))); 

如果你是doing your tests in F#,與Foq,你會寫爲:

Mock<IFoo>.With(fun x -> 
    <@ x.Method(any()) --> 7 
     x.Property --> "Hi" @>) 
|> fixture.Inject 

(表達對-->權僅僅是代碼,例如,你可以把算法的東西在裏面當你編寫它時,你會得到智能感知和類型檢查)。或(仍與FOQ):

fixture.Inject <| 
    Mock<IFoo>.With(fun x -> <@ 
     x.Method(any()) --> 7 
     x.Property --> "Hi" @>) 

或(假設接口有意義的完全實現),可以使用F#對象表達式:

fixture.Inject { new IFoo with 
    member x.Method _ = 7 
    member x.Property with get() = "Hi" }