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

Mock object that sets an item from session in its constructor

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

第 3 方库的反编译代码:

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

我得到:

An exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll but was not handled in user code

也试过这个:

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 是一个 public class,它有一个静态实例(当前)属性。

I have a 3rd party type BillingAddress which when decompiled I noticed sets some properties in it's constructor (from session). I would like to mock such type and send it to a utility function.

如果您没有权利或不能更改 BillingAddress 的代码,因为它是第三方 API 那么只需通过创建一个新的 class 来隐藏它那会把它包起来。

public class BillingAddressWrapper
{
     private BillingAddress _billingAddress;

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

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

有了新的 class,您将拥有做您想做的事的所有能力,为了测试目的而模拟它只是其中之一。

在编写应用程序代码时,请始终避免与第三方 API 绑定。为什么?因为它们中的大多数都为您提供了您想要在应用程序中使用的东西的特定实现。想象一下,如果您将来不得不选择另一个第三方 API 来替换实际的第三方,因为它已经过时或者没有更多关于 API 的支持,您将浪费很多时间来采取行动到新 API.