2016-09-30 6 views
1

В justmock мы можем вернуть издевались экземпляры вместо реальных экземпляров, устраивая вызов конструктора какДразнящий вызов конструктора в Justmock не выполняется для UrlHelper

Mock.Arragne(()=>new MyClass(Arg.IsAny<string>())).IgnoreInstance().Returns(Mock.Create<MyClass>()); 

, но когда я попробовал то же самое с UrlHelper класса, а не издевались типа, фактический тип получает экземпляр. Может кто-нибудь сказать, если есть какая-либо ошибка в этом:

UrlModel класс

public class UrlModel 
    { 
     private UrlHelper url; 
     public UrlModel() 
     { 
      url = new UrlHelper(HttpContext.Current.Request.RequestContext); 
     } 
    } 

Метод испытания:

public void UrlTest() 
{ 
    Mock.Arrange(() => HttpContext.Current.Request.RequestContext).Returns(Mock.Create<RequestContext>()); 

    var mockedUrl = Mock.Create<UrlHelper>(); 

    Mock.Arrange(() => new UrlHelper(Arg.IsAny<RequestContext>())) 
     .IgnoreArguments() 
     .IgnoreInstance() 
     .Returns(mockedUrl); 

    //Here url will have actual instance instead of mocked instance 
    var model = new UrlModel(); 

    //Assert is ommitted for bravity .. 
} 

ответ

0

Вы вручную инстанцировании экземпляр UrlHelper в конструкторе UrlModel. UrlModel теперь плотно соединен с UrlHelper (новый - клей). Сделайте абстракцию зависимостей, которые вы можете позволить для более слабосвязанной модели и улучшенной макете способности

public interface IUrlHelperAccessor { 
    UrlHelper UrlHelper { get; } 
} 

и впрыснуть, что в UrlModel

public class UrlModel { 
    private UrlHelper url; 
    public UrlModel(IUrlHelperAccessor accessor) { 
     url = accessor.UrlHelper; 
    } 
    //...other code 
} 

Теперь вы оформляете тест соответственно

public void UrlTest() { 
    Mock.Arrange(() => HttpContext.Current.Request.RequestContext) 
     .Returns(Mock.Create<RequestContext>()); 

    var mockedUrl = Mock.Create<UrlHelper>(Constructor.Mock); 
    var mockedAccessor = Mock.Create<IUrlHelperAccessor>(); 

    Mock.Arrange(() => mockedAccessor.UrlHelper).Returns(mockedUrl); 

    //Here url will have actual instance instead of mocked instance 
    var model = new UrlModel(mockedAccessor); 

    //Assert is omitted for brevity .. 

} 
1

Вы можете использовать Typemock для тестирования кода без добавления каких-либо новых интерфейсов, путем подделки RequestContext и изменения правильности у Поведения:

[TestMethod,Isolated] 
public void UrlTest() 
{ 
    //Arrange 
    var fakeRequest = Isolate.Fake.Instance<RequestContext>(); 
    Isolate.WhenCalled(() => HttpContext.Current.Request.RequestContext).WillReturn(fakeRequest); 

    //Act 
    var res = new UrlModel(); 
    //getting the private field so it can be asserted 
    var privateField = Isolate.NonPublic.InstanceField(res, "url").Value as UrlHelper; 

    //Assert 
    Assert.AreEqual(fakeRequest, privateField.RequestContext); 
} 
0

Единственная причина, почему конструктор издевается в этом случае не будет работать в том, что UrlModel класса является часть тестового класса - код в тестовых классах не сам mockable.

Другая вещь, которая приходит на ум, состоит в том, что вы могли быть введены в заблуждение отладчиком. Когда вы создаете макет не абстрактного типа при запуске профайлера, сам экземпляр имеет тот же тип, что и вымышленный тип - это не производный тип, скажем, UrlHelperMock, как в случае, когда профайлер не запущен. Можете ли вы подтвердить использование функции отладчиков Make Object ID, что экземпляр mock и экземпляр, возвращенные с new, действительно не совпадают?

Вы пришли к выводу, что выражение new выражение не работает, потому что ваши аранжировки UrlHelper не работали, или это было что-то еще?