How to mock a ReadOnlyCollection<T> property using moq

狂风中的少年 提交于 2019-12-11 08:24:37

问题


I'm trying to mock this ReadOnlyCollection property:

private readonly IList<MyClass> myList = new List<MyClass>();
public virtual ReadOnlyCollection<MyClass> MyList
{
   get
   {
       return new ReadOnlyCollectionBuilder<MyClass>(this.myList).ToReadOnlyCollection();
   }
}

using this mock (as seen here):

IList<MyClass> mockList = GetElements();
mockObj.SetupGet<IEnumerable<MyClass>>(o => o.myList).Returns(mockList);

However at runtime I get an InvalidCastException:

Unable to cast object of type 'System.Collections.Generic.List`1[MyClass]' to
type 'System.Collections.ObjectModel.ReadOnlyCollection`1[MyClass]'.

What am I doing wrong?


回答1:


Suppose your code really looks like (otherwise it will not compile):

// Arrange
IList<MyClass> stakeHoldersList= GetElements();
mockObj.SetupGet<IEnumerable<MyClass>>(o => o.MyList).Returns(stakeHoldersList);
// Act on SUT which uses mockObj

You have property MyList of type ReadOnlyCollection<MyClass> but you are trying to return IEnumerable<MyClass>. Thats why you get that error. So, change:

ReadOnlyCollection<MyClass> stakeHoldersList = new ReadOnlyCollection<MyClass>(GetElements());
mockObj.SetupGet<ReadOnlyCollection<MyClass>>(o => o.MyList).Returns(stakeHoldersList);

To avoid such runtime errors, do not specify type of SetupGet method. In this case return value type will inferred from property type and you will get error immediately (code won't compile if return value type does not match property type):

mockObj.SetupGet(o => o.MyList).Returns(stakeHoldersList);



回答2:


You can't mock the private readonly property myList, what you can do is override the public property MyList since it is marked virtual. In order to do that, you need to update this code:

IList<MyClass> mockList = GetElements();
mockObj.SetupGet<IEnumerable<MyClass>>(o => o.myList).Returns(mockList);

to this:

var mockList = new ReadOnlyCollection<MyClass>(GetElements());
mockObj.Setup(o => o.MyList).Returns(mockList);



回答3:


A little late, but I think this can be a little less code.

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


来源:https://stackoverflow.com/questions/10199544/how-to-mock-a-readonlycollectiont-property-using-moq

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!