模拟对象,在其构造函数中设置会话中的项目

时间:2016-02-13 17:56:04

标签: c# .net moq

我有第三方类型BillingAddress,在反编译时,我注意到它在其构建器(来自会话)中设置了一些属性。我想模仿这种类型并将其发送到实用功能:

// need to be able to unit test this method
public static ShippingAddress Convert(BillingAddress billingAddress){
   var sAddress = new ShippingAddress();
   sAddress.City = billingAddress.City;
   // setting several shipping address properties
   //...
}

我无法创建BillingAddress的新实例,因为它的会话构造函数代码(当我执行新的BillingAddress()时会抛出异常 - 因为它只能在特定的上下文中工作)

第三方lib的解除代码:

public BillingAddress(); // calls base() => gets session stuff
protected BillingAddress(SerializationInfo info, StreamingContext context);

所以,我试图模仿BillingAddress。这可能吗?如何?

我试过了:

...
Mock<BillingAddress> m = new Mock<BillingAddress>();
var sAddress = Converter.Convert(c, m.Object);

我明白了:

  

类型&#39; System.Reflection.TargetInvocationException&#39;的异常   发生在mscorlib.dll中但未在用户代码中处理

也尝试了这个:

var ac = new Mock<BillingAddress>(MockBehavior.Loose, new object[] { new Mock<SerializationInfo>(), new StreamingContext()});

同样的错误

更新

BillingAddress的构造函数:

// Decompiled code
public BillingAddress()
      : base(OrderContext.Current.MetaClass)
    {

有没有办法模拟BillingAddress()=&gt;所以,当它调用基数时,它会注入一个模拟OrderContext?这样的事情可能吗?

OrderContext是一个具有静态实例(当前)属性的公共类。

1 个答案:

答案 0 :(得分:3)

  

我有第三方类型BillingAddress,在反编译时,我注意到它在其构建器(来自会话)中设置了一些属性。我想模仿这种类型并将其发送到实用功能。

如果您没有权利或者只是无法更改BillingAddress的代码,因为它是第三方API,那么只需通过创建一个新的类来隐藏它它。

public class BillingAddressWrapper
{
     private BillingAddress _billingAddress;

     public string City 
     {
          get { return _billingAddress.City; }
     }

     // Creatae properties that wrap BillingAddress properties as much as you want.
}

使用新课程,您将拥有完成所需工作的所有功能,并且出于测试目的而嘲笑它只是其中之一。

在编写应用程序代码时,始终避免与第三方API绑定。为什么?因为它们中的大部分都为您提供了要在应用程序中使用的特定实现。想象一下,如果您必须选择另一个第三方API来替换实际的API,因为它已经过时或者没有对API的支持,您将失去大量时间来迁移到新的API