如何嘲弄一个ReadOnlyCollection 使用MOQ财产(How to mock a

2019-10-16 14:47发布

我想嘲笑这个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]'.

我究竟做错了什么?

Answer 1:

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

// 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);


Answer 2:

你不能嘲笑私人只读属性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);


Answer 3:

有点晚,但我认为这可能是一个少的代码。

mockObj.SetupGet(o => o.MyList).Returns(GetElements().AsReadOnly);


文章来源: How to mock a ReadOnlyCollection property using moq
标签: c# moq