2011-05-11 70 views
0

我正在嘗試使用FakeItEasy來模擬一個對象,該對象是我創建的C#類的成員。如何在C#中模擬類成員?

的FakeItEasy文檔表明您與此類似的方式僞造的對象:

private static var m_physics = A.Fake<IPhysics>(); 

也就是說,使用「無功」的關鍵字。

但是,在這種情況下,C#編譯器不喜歡在非本地上下文中使用var這一事實。我得到這個錯誤:

上下文關鍵字「變種」只能出現在局部變量聲明

內我不能嘲笑的對象,這不是地方?

+3

我想你混淆了隱式類型嘲諷。如果將'var'更改爲返回的實際類型,則不會有問題。 – Tejs 2011-05-11 17:12:06

+0

嘲笑班級成員是如此不好... – pixelbobby 2011-05-11 17:12:35

+0

該類型還不存在。因此,需要模擬。 – Buggieboy 2011-05-11 17:15:27

回答

6

我認爲你錯過了嘲笑/存根(stub)這一點。當不希望被測主題通過或失敗時,模擬和存根用於測試,具體取決於它所依賴的其他組件。因此,你所做的是將這些顯式實現交換出來,以便在測試中完全控制這些依賴關係的模擬/存根。

class Foo { 
    public Foo(IBar bar) { } 
    public object M() { // do something with IBar } 
} 

這裏FooIBar的依賴。我們想測試Foo.M。我們不希望測試通過或失敗,這取決於我們對FooIBar的具體實施是否有效。

[Fact] 
public void MDoesWhatItIsSupposeToDo() { 
    var foo = new Foo(new Bar()); 
    object expected = // expected result 
    Assert.Equal(expected, foo.M()); 
} 

如果Bar被打破了這一測試可能失敗,即使Foo可能完全正確編碼。所以,你在一個模擬/存根Sub要防止措施這一

[Fact] 
public void MDoesWhatItIsSupposeToDo() { 
    var bar = A.Fake<IBar>(); 
    // set up bar to do what is expected of IBars 
    var foo = new Foo(bar); 
    object expected = // expected result 
    Assert.Equal(expected, foo.M()); 
} 

現在這個測試只傳遞或者Foo正確與否編碼,獨立於你的IBar具體的實現是否是正確的失敗。

這是嘲笑的地方。

所以所有這一切都是說,你沒有正確使用模擬。

Can't I mock an object that's not local?

你可以,但不是你所做的。首先,字段不能被隱式輸入。其次,你不要像你所做的那樣明確地嘲笑這個領域。相反,你不喜歡這樣寫道:

class Whatever { 
    private IPhysics m_physics; 

    public Whatever(IPhsyics physics) { this.m_physics = physics; } 
} 

然後:

var physics = A.Fake<IPhysics>(); 
var whatever = new Whatever(physics); 
+1

+1很好的廣義解釋! – 2011-05-11 17:33:01

+0

好的,這是一個很好的總結。謝謝。這並不是因爲我錯過了mock的觀點,因爲我想用現有的機制(mocks)來編譯A類,當A包含B的實例並且B尚未實現時。上面包含的最後一點似乎給了我一個這樣做的方法。 – Buggieboy 2011-05-11 17:40:46

+1

@Buggieboy:但這就是爲什麼你對接口('IPhysics')進行編碼而不是具體的實現。這個問題與嘲笑無關。 – jason 2011-05-11 18:08:03

0

只能在本地環境中使用'var'關鍵字,如功能塊。您不能將類成員聲明爲「var」。

+0

對。這就是錯誤信息所說的。這就是由於這個限制導致如何使用模擬框架的問題。 – Buggieboy 2011-05-11 17:29:42