Moq Mocking ChildProperty无法使其工作?

Moq Mocking ChildProperty无法使其工作?,moq,Moq,我正在尝试测试嵌套在子类中的属性。 我总是出错。 我错过什么了吗? 是否可以在moq中测试子属性 我有以下几点 [Test] public void Should_be_able_to_test_orderCollection() { var orderViewMock = new Mock<IOrderView>(); orderViewMock.SetupGet(o => o.Customer.OrderDataCollec

我正在尝试测试嵌套在子类中的属性。 我总是出错。 我错过什么了吗? 是否可以在moq中测试子属性

我有以下几点

     [Test]
public void Should_be_able_to_test_orderCollection()
    {
        var orderViewMock = new Mock<IOrderView>();
        orderViewMock.SetupGet(o => o.Customer.OrderDataCollection.Count).Returns(2);          

        orderViewMock.SetupSet(o => o.Customer.OrderDataCollection[1].OrderId = 1);

        orderViewMock.VerifySet(o => o.Customer.OrderDataCollection[1].OrderId=1);
    }

    public class CustomerTestHelper
    {
        public static CustomerInfo GetCustomer()
        {
            return new CustomerInfo
           {
               OrderDataCollection = new OrderCollection
                 {
                     new Order {OrderId = 1},
                     new Order {OrderId = 2}
                 }
           };

        }
    }
    public class CustomerInfo
    {
        public OrderCollection OrderDataCollection { get; set; }
    }

    public class OrderCollection:List<Order>
    {
    }

    public class Order
    {
        public int OrderId { get; set; }
    }
    public interface  IOrderView
    {
        CustomerInfo Customer { get; set; }
    }
[测试]
public void应该能够测试orderCollection()
{
var orderViewMock=new Mock();
orderViewMock.SetupGet(o=>o.Customer.OrderDataCollection.Count);
orderViewMock.SetupSet(o=>o.Customer.OrderDataCollection[1].OrderId=1);
orderViewMock.VerifySet(o=>o.Customer.OrderDataCollection[1].OrderId=1);
}
公共类CustomerTestHelper
{
公共静态CustomerInfo GetCustomer()
{
返回新CustomerInfo
{
OrderDataCollection=新建OrderCollection
{
新订单{OrderId=1},
新订单{OrderId=2}
}
};
}
}
公共类CustomerInfo
{
public OrderCollection OrderDataCollection{get;set;}
}
公共类OrderCollection:列表
{
}
公共阶级秩序
{
公共int-OrderId{get;set;}
}
公共界面IOrderView
{
CustomerInfo客户{get;set;}
}

如果你有正确的抽象概念,这绝对是可能的。你需要模仿你的
客户
及其孩子,这样你的例子才能起作用,比如:

var customerMock = new Mock<ICustomer>();
orderViewMock.SetupGet(o => o.Customer).Returns(customerMock.Object);
var customerMock=new Mock();
orderViewMock.SetupGet(o=>o.Customer).Returns(customerMock.Object);
等等。对于要使用模拟控制的子对象的整个层次结构。希望它有意义


/Klaus

您不能模拟CustomerInfo的OrderDataCollection属性,因为它是具体类上的非虚拟属性

解决此问题的最佳方法是从CustomerInfo提取一个接口,并让IOrderView返回该接口:

public interface IOrderView
{
    ICustomerInfo Customer { get; set; }
}

您将得到一个运行时错误,如您所发现的:

System.ArgumentException: Invalid setup on a non-overridable member:
o => o.Customer.OrderDataCollection.Count
at Moq.Mock.ThrowIfCantOverride(Expression setup, MethodInfo methodInfo)
您可以模拟IOrderView并返回所需的任何CustomerInfo实例,但也可以尝试模拟CustomerInfo和OrderCollection。正如Mark Seemann提到的,您只能模拟接口和虚拟属性/方法。这几乎适用于除(商业)之外的任何模拟/隔离框架


正如其他人已经指出的,解决问题的一种方法是为客户返回一个接口。

谢谢您的回复。仍然无法获取集合。计数工作我想验证mock.Customer.OrderCollection.Count=2这可能吗?orderViewMock.SetupGet(o=>o.Customer.OrderCollection).Returns(orderViewMock.Object.Customer.OrderCollection);以上就是我所尝试的。正如上面@Mark Seemann所说的,您只能模拟抽象类和接口,因此您也需要抽象
OrderCollection
,这样才能工作。@devnet247-您需要让您的ICCustomer返回一个IOrderCollection(或ICollection,等等),可能是IOrder实例。或者,请参见感谢您的回复。你是说我应该使该属性虚拟化,它会工作吗?使OrderDataCollection虚拟化也可能工作。另一方面,集合属性应该是只读的。非常感谢,我现在似乎明白了。我制作了一个接口