2012-04-17 36 views
2

我試圖嘲弄這個名單嘲笑私人只讀的IList 屬性: 如何用最小起訂量

private readonly IList<MyClass> myList = new List<MyClass>(); 

使用這個(如圖here):

IList<MyClass> mockList = Builder<MyClass>.CreateListOfSize(5).Build(); 
mockObj.SetupGet<IEnumerable<MyClass>>(o => o.myList).Returns(stakeHoldersList); 

但是在運行時,我得到InvalidCastException:

Unable to cast object of type 'System.Collections.Generic.List`1[MyClass]' to 
type 'System.Collections.ObjectModel.ReadOnlyCollection`1[MyClass]'. 

我在做什麼錯?

+0

可以公開這個私有隻讀成員的公共虛擬財產?另外,如果有問題的項目是私人的,這聽起來像你沒有測試正確的組件。 – Tejs 2012-04-17 19:30:55

+0

@Tejs你是對的,請看更新 - 現在更準確 - 問題:) – epzee 2012-04-17 19:55:31

+0

請不要編輯一個完全改變它的含義的問題。編輯應該是澄清,而不是從根本上改變意義。如果你想問一個不同的問題...問一個不同的問題。 – jason 2012-04-17 20:57:11

回答

6

嗯,我認爲嘲笑一個私人實現細節是很奇怪和坦率地錯誤的。你的測試不應該依賴於私有的實現細節。

,但我會做到這一點,如果我是你的方式是增加一個構造函數:

public Foo { 
    private readonly IList<MyClass> myList; 
    public Foo(IList<MyClass> myList) { this.myList = myList; } 
} 

,然後用最小起訂量來嘲笑的IList<MyClass>一個實例,並傳遞通過構造函數。

如果你不喜歡這個建議,或者,做一個虛擬財產:

public Foo { 
    private readonly IList<MyClass> myList = new MyList(); 
    public virtual IList<MyClass> MyList { get { return this.myList; } } 
} 

,然後用最小起訂量來覆蓋該屬性。

不過,你做錯了。

+0

這基本上是我要說的一切。無論如何,你只應該測試公開可見的界面。 – Tejs 2012-04-17 19:38:51

+0

@Tejs你絕對正確。請參閱新的問題:http://stackoverflow.com/questions/10199544/how-to-mock-a-readonlycollectiont-property-using-moq – epzee 2012-04-17 21:40:20

+0

這就是所謂的依賴注入。不錯的演出! – Levitikon 2013-04-09 15:47:39

0

你有一個字段,但試圖設置屬性獲取。

改變myList中財產可能工作(不是MOQ這裏專家):

private readonly IList<MyClass> myListFiled = new List<MyClass>(); 
private IList<MyClass> myList { 
    get 
    {return myListFiled;} 
}