创建一个虚拟集合<>具有私有设置的属性:“在非虚拟上的设置无效”

本文关键字:设置 虚拟 属性 无效 集合 一个 创建 | 更新日期: 2023-09-27 18:17:37

我遇到了一个问题,我试图模拟一个包含ICollection<>类型的属性Items的对象。我得到以下错误:

系统。NotSupportedException:在非虚拟(在VB中可重写)成员上设置无效:m => m. items

问题是属性Items已经是虚的

我复制了我在项目中得到的错误,在下面的沙盒中:

public class ItemList
{
    public virtual int Id { get; set; }
}
public class SpecialList
{
    public virtual string Token { get; internal set; }
    public virtual ICollection<ItemList> Items { get; private set; }
}

这个错误发生在我的测试,当我尝试SetupProperty像这样:

[TestFixture]
public class TestSpecialList
{
    [Test]
    public void Mocking_Virtual_ICollection()
    {
        var mockModel = new Mock<SpecialList>();
        var listItem = new List<ItemList> {new ItemList {Id = 007}};
        mockModel.SetupProperty(m => m.Items, listItem);
    }
}

我做错了什么吗?是否有可能Moq一个包含ICollection<>属性的对象?

创建一个虚拟集合<>具有私有设置的属性:“在非虚拟上的设置无效”

试一试:

mockModel.Setup(m => m.Items).Returns(listItem);
mockModel.SetupGet(m => m.Items).Returns(listItem);

当您想要跟踪其值时,可以使用SetupProperty方法,请参阅moq wiki。虽然我不太确定SetupProperty失败的原因,因为它的目的是能够传递和检索属性值,但它似乎可能是由私有get引起的。

为了清楚起见,让我们假设您的属性有一个公共集。在这种情况下,当使用SetupSetupGet时,执行mockModel.Object.Items = new List<ItemList>();之类的操作将没有效果,您仍然会看到单个项目的列表。但是对于SetupProperty,相同的语句会改变属性返回的值。

基本上SetupProperty允许获取和设置属性的值,这就是为什么我认为它不能与私有集一起使用。