Reputation: 21338
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:
// 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
//...
}
I can't create a new instance of BillingAddress because of it's Session constructor code (when I do new BillingAddress() it throws an exception - because it only works in specific context)
Decomipled code of 3rd party lib:
public BillingAddress(); // calls base() => gets session stuff
protected BillingAddress(SerializationInfo info, StreamingContext context);
So, I'm trying to mock BillingAddress. Is this possible? how?
I tried this:
...
Mock<BillingAddress> m = new Mock<BillingAddress>();
var sAddress = Converter.Convert(c, m.Object);
I get:
An exception of type 'System.Reflection.TargetInvocationException' occurred in mscorlib.dll but was not handled in user code
also tried this:
var ac = new Mock<BillingAddress>(MockBehavior.Loose, new object[] { new Mock<SerializationInfo>(), new StreamingContext()});
same error
UPDATE:
Constructor of BillingAddress:
// Decompiled code
public BillingAddress()
: base(OrderContext.Current.MetaClass)
{
Is there any way to mock BillingAddress() => so that when it calls the base it will inject a Mock of OrderContext? Is something like this possible?
OrderContext is a public class that has a static Instance (Current) property.
Upvotes: 3
Views: 340
Reputation: 23220
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.
If you don't have the right or just can't change the code of BillingAddress
because it's a thrid party API then just hide it by creating a new class that will wrap it.
public class BillingAddressWrapper
{
private BillingAddress _billingAddress;
public string City
{
get { return _billingAddress.City; }
}
// Creatae properties that wrap BillingAddress properties as much as you want.
}
With the new class you will have all capabilities to do what you want and mocking it for test purposes is just one of them.
Always avoid being tied to a third party APIs when coding your application. Why? Because allmost of them give you a scpecific implementation of something you want to use into your application. Imagine in the furutre if you have to choose another third party API to replace the actual one because it's is obsolete or there is no more support about the API you will lost a lot of time to make the move to the new API.
Upvotes: 3