我想嘲笑这个ReadOnlyCollection属性:
private readonly IList<MyClass> myList = new List<MyClass>();
public virtual ReadOnlyCollection<MyClass> MyList
{
get
{
return new ReadOnlyCollectionBuilder<MyClass>(this.myList).ToReadOnlyCollection();
}
}
使用这种模拟(如看到这里 ):
IList<MyClass> mockList = GetElements();
mockObj.SetupGet<IEnumerable<MyClass>>(o => o.myList).Returns(mockList);
然而,在运行时,我得到一个InvalidCastException:
Unable to cast object of type 'System.Collections.Generic.List`1[MyClass]' to
type 'System.Collections.ObjectModel.ReadOnlyCollection`1[MyClass]'.
我究竟做错了什么?
假设你的代码真的看起来像(否则它不会编译):
// Arrange
IList<MyClass> stakeHoldersList= GetElements();
mockObj.SetupGet<IEnumerable<MyClass>>(o => o.MyList).Returns(stakeHoldersList);
// Act on SUT which uses mockObj
你有类型的财产MYLIST ReadOnlyCollection<MyClass>
,但你试图返回IEnumerable<MyClass>
。 这就是为什么你得到这个错误。 因此,更改:
ReadOnlyCollection<MyClass> stakeHoldersList = new ReadOnlyCollection<MyClass>(GetElements());
mockObj.SetupGet<ReadOnlyCollection<MyClass>>(o => o.MyList).Returns(stakeHoldersList);
为了避免这样的运行时错误,不指定SetupGet方法的类型。 在这种情况下返回值的类型将物业类型推断,你会立即得到错误(如果返回值的类型不匹配属性类型的代码不会编译):
mockObj.SetupGet(o => o.MyList).Returns(stakeHoldersList);
你不能嘲笑私人只读属性myList
,你可以做的是覆盖公共财产MyList
,因为它被标记为虚。 为了做到这一点,你需要更新此代码:
IList<MyClass> mockList = GetElements();
mockObj.SetupGet<IEnumerable<MyClass>>(o => o.myList).Returns(mockList);
为此:
var mockList = new ReadOnlyCollection<MyClass>(GetElements());
mockObj.Setup(o => o.MyList).Returns(mockList);
有点晚,但我认为这可能是一个少的代码。
mockObj.SetupGet(o => o.MyList).Returns(GetElements().AsReadOnly);