【问题标题】:Moq, how to moq objects with private constructor?起订量,如何使用私有构造函数来起订量对象?
【发布时间】:2019-05-13 18:00:36
【问题描述】:

我有这个类层次结构

public class Order
{  
    private Client _client;
    public virtual Client { get => _client; }

    private OrderNumber _orderNumber;
    public virtual OrderNumber OrderNumber { get => _orderNumber; }

    private ShippingDetails _shippingDetails;
    public virtual ShippingDetails ShippingDetails { get => _shippingDetails; }

    private IList<Product> _products;
    protected internal virtual IEnumerable<Product> Products { get => _products; }


    public Order() { }

    public virtual void CreateDraftForClient(int id)
    {
         /// => business rule validation of value 

         _client= new Client(id);

          /// => event     
     }
}

public class Client
{
    private int _id;
    public virtual int Id { get => _id; }

    private Client() { }
    protected internal Client(int id) 
    {
        SetId(id);
    }

    private void SetId(int id)
    {
        _id = id; 
    }
}

并且想要创建一个完全初始化的订单模拟

 clientMock = new Mock<Client>();
 clientMock.SetupGet(prop => prop.Client).Returns(1);

 orderMock = new Mock<Order>();
 orderMock.SetupGet(prop => prop.Client).Returns(orderMock.Object);

例外:

Message: System.AggregateException : One or more errors occurred. (Can not instantiate proxy of class: Client. Could not find a parameterless constructor.) (The following constructor parameters did not have matching fixture data: eRxTestSetup testSetup)
---- Castle.DynamicProxy.InvalidProxyConstructorArgumentsException : Can not instantiate proxy of class: Client. Could not find a parameterless constructor.
---- The following constructor parameters did not have matching fixture data: eRxTestSetup testSetup

有什么方法可以在不改变客户端结构的情况下做到这一点?或者如果没有,我还有什么其他选择?

【问题讨论】:

  • 您可以尝试使用反射创建它或创建一个调用受保护构造函数的派生类
  • 是的,这是目前的情况,但我希望有一个开箱即用的解决方案
  • 好吧,这感觉就像XY problem。你真正想要达到的最终目标是什么?你到底想测试什么?
  • 我想要做的是创建一些用测试所需数据初始化的对象。所以我有一个 SetUp 类,在这个类构造函数中,我为我拥有的每个实体创建模拟。 Setup 类提供了一组方法,例如初始化处于不同状态的实体,然后返回实际对象 Mock.Object。方法 GetEntityInFullValidState() 的示例,它将使用 EntityMock 创建一个完全初始化的实体(所有道具和属性)。我已经根据我的真实场景更新了课程,也许它更有意义
  • 看看clientMock = new Mock&lt;Client&gt;(1); 是否有所作为。

标签: unit-testing testing mocking moq


【解决方案1】:

鉴于Order 的当前定义,没有简单的方法可以模拟它。

尝试通过受保护的构造函数通过将所需参数传递给模拟来创建模拟

int id = 1;
var clientMock = new Mock<Client>(id);
clientMock.SetupGet(prop => prop.Id).Returns(id);

var orderMock = new Mock<Order>();
orderMock.SetupGet(prop => prop.Client).Returns(clientMock.Object);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多