我正在尝试模拟这个ReadOnlyCollection属性:
private readonly IList<MyClass> myList = new List<MyClass>();
public virtual ReadOnlyCollection<MyClass> MyList
{
get
{
return new ReadOnlyCollectionBuilder<MyClass>(this.myList).ToReadOnlyCollection();
}
}
使用此模拟(如here所示):
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]'.
我做错了什么?
答案 0 :(得分:1)
您无法模拟私有只读属性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);
答案 1 :(得分:1)
假设您的代码看起来很像(否则它将无法编译):
// Arrange
IList<MyClass> stakeHoldersList= GetElements();
mockObj.SetupGet<IEnumerable<MyClass>>(o => o.MyList).Returns(stakeHoldersList);
// Act on SUT which uses mockObj
您拥有类型为ReadOnlyCollection<MyClass>
的属性MyList,但您尝试返回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);
答案 2 :(得分:0)
有点晚了,但是我认为这可以减少一些代码。
mockObj.SetupGet(o => o.MyList).Returns(GetElements().AsReadOnly);