我有一个第三方类型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的新实例,因为它是Session构造函数代码(当我执行新的BillingAddress()时,它将引发异常-因为它仅在特定上下文中有效)

第三方库的分解代码:

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);


我得到:


  类型'System.Reflection.TargetInvocationException'的异常
  发生在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()=>,以便在调用基数时注入一个OrderContext模拟对象?这样的事情可能吗?

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

最佳答案

我有一个第三方类型BillingAddress,在反编译时,我注意到它在构造函数中(从会话开始)设置了一些属性。我想模拟这样的类型并将其发送到实用程序函数。


如果您没有权限,或者因为第三方API不能更改BillingAddress的代码,则可以通过创建一个将其包装的新类将其隐藏。

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。

10-06 10:37