模拟 ChildProperty 无法使其工作?

发布于 2024-08-20 14:19:52 字数 1215 浏览 2 评论 0原文

我正在尝试测试嵌套在子类中的属性。 我总是收到错误。 我错过了什么吗? 是否可以在最小起订量中测试子属性。

我有以下内容

     [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; }
    }

I am trying to test a property that is nested in a child class.
I always get an error.
Am I missing something?
Is it possible to test a child property in moq.

I have the following

     [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; }
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

韶华倾负 2024-08-27 14:19:52

您无法模拟 CustomerInfo 的 OrderDataCollection 属性,因为它是具体类上的非虚拟属性。

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

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

You can't mock the OrderDataCollection property of CustomerInfo because it's a non-virtual property on a concrete class.

The best way to fix this would be to extract an interface from CustomerInfo and let IOrderView return that instead:

public interface IOrderView
{
    ICustomerInfo Customer { get; set; }
}
花想c 2024-08-27 14:19:52

如果你有正确的抽象,这绝对是可能的。您还需要模拟您的 Customer 及其子对象,以便您的示例能够工作,例如:

var customerMock = new Mock<ICustomer>();
orderViewMock.SetupGet(o => o.Customer).Returns(customerMock.Object);

对于您想要使用模拟控制的子对象的整个层次结构。希望这是有道理的。

/克劳斯

It is definitely possible if you have the right abstractions. You need to mock your Customer and its children too, for your example to work, like:

var customerMock = new Mock<ICustomer>();
orderViewMock.SetupGet(o => o.Customer).Returns(customerMock.Object);

etc. for the entire hierarchy of child objects you want to control with mocks. Hope it makes sense.

/Klaus

妄想挽回 2024-08-27 14:19:52

正如您所发现的,您将收到运行时错误:

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 (商业)。

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

You will get a runtime error, as you've found:

System.ArgumentException: Invalid setup on a non-overridable member:
o => o.Customer.OrderDataCollection.Count
at Moq.Mock.ThrowIfCantOverride(Expression setup, MethodInfo methodInfo)

You can mock the IOrderView and return any CustomerInfo instance you want, but you're also trying to mock CustomerInfo and OrderCollection. As Mark Seemann mentioned, you can only mock interfaces and virtual properties/methods. This will hold true for almost any mocking/isolation framework except for Typemock (commercial).

As others have already stated, one way to solve the problem is to return an interface for the customer.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文