2012-04-17 66 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;} 
}