2016-02-13 5 views
3

У меня есть сторонний тип BillingAddress который при декомпиляции заметил, что некоторые свойства в его конструкторе (с сеанса) установлены. Я хотел бы, чтобы дразнить такой тип и отправить его в функцию полезности:Mock object, который устанавливает элемент из сеанса в его конструкторе

// 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() он бросает исключение - потому что она работает только в определенном контексте)

Decomipled код 3 партии 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); 

я получаю:

Исключение типа 'System.Reflection.TargetInvocationException' произошло в mscorlib.dll, но не был обработан в пользовательском коде

также пробовал:

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

же ошибка

UPDATE:

Конструктор BillingAddress:

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

Есть ли способ издеваться BillingAddress() => так что при вызове базы он будет вводить макет заказаКонтекст? Что-то вроде этого возможно?

OrderContext - это открытый класс, обладающий свойством static Instance (Current).

+0

Итак, вы имеете в виду 'BillingAddress' обращается к некоторому статическому объекту?Можете ли вы издеваться над этим *, чтобы вы могли правильно создать платежный адрес самостоятельно? – poke

+0

есть. это доступ к материалам из сеанса при создании нового BillingAddress(). Так я должен был бы издеваться над дизайнером? если да, то как? – ShaneKm

+0

Статик не может насмехаться с Moq. Но вы можете создать интерфейс для стороннего типа и высмеять этот интерфейс. – dee

ответ

3

У меня есть сторонний тип BillingAddress, который при декомпиляции я заметил, что некоторые свойства содержатся в его конструкторе (из сеанса). Я хотел бы высмеять такой тип и отправить его в функцию утилиты.

Если вы не имеете права или просто не можете изменить код BillingAddress, потому что это thrid стороны 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.

+0

есть ли способ создать moq, чтобы он не вызывал конструктор base()? будет ли это работать? – ShaneKm

+0

Нет, вы не можете этого делать. Конструктор по умолчанию всегда вызывается при создании нового экземпляра класса, даже если вы вызываете construstor с параметром. Base() является конструктором по умолчанию. – CodeNotFound

+0

CodeNotFound - вы можете увидеть мое обновление – ShaneKm

Смежные вопросы