1

我试图模拟这个 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]'.

我究竟做错了什么?

4

3 回答 3

2

假设你的代码真的看起来像(否则它不会编译):

// 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);
于 2012-04-17T21:52:38.687 回答
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);
于 2012-04-17T21:47:38.970 回答
0

有点晚了,但我认为这可以少一点代码。

mockObj.SetupGet(o => o.MyList).Returns(GetElements().AsReadOnly);
于 2019-06-17T09:41:42.747 回答