我正在尝试测试嵌套在子类中的属性。 我总是得到一个错误。 我错过了什么吗? 是否可以在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; }
}
答案 0 :(得分:3)
您无法模拟CustomerInfo的OrderDataCollection属性,因为它是具体类的非虚拟属性。
解决这个问题的最佳方法是从CustomerInfo中提取一个接口,然后让IOrderView返回:
public interface IOrderView
{
ICustomerInfo Customer { get; set; }
}
答案 1 :(得分:1)
如果你有正确的抽象,这绝对是可能的。你需要嘲笑你的Customer
及其子女,为你的榜样工作,例如:
var customerMock = new Mock<ICustomer>();
orderViewMock.SetupGet(o => o.Customer).Returns(customerMock.Object);
等。对于要使用模拟控制的子对象的整个层次结构。希望它有意义。
/克劳斯
答案 2 :(得分:0)
您将收到运行时错误,如您所见:
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所提到的,您只能模拟接口和虚拟属性/方法。除了Typemock(商业)之外,这几乎适用于任何模拟/隔离框架。
正如其他人已经说过的,解决问题的一种方法是为客户返回一个界面。