簡體   English   中英

對於 UrlHelper,Justmock 中的模擬構造函數調用失敗

[英]Mocking constructor call in Justmock fails for UrlHelper

在 justmock 中,我們可以通過安排構造函數調用來返回模擬實例而不是實際實例

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

但是當我對UrlHelper類進行相同嘗試時,實際類型不是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 .. 
}

您可以使用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);
}

您正在UrlModel的構造函數中手動實例化UrlHelper的實例。 UrlModel現在與UrlHelper緊密耦合(新的是glue )。 進行依賴抽象,您可以允許更松散耦合的模型和改進的模擬能力

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 .. 

}

在這種情況下,構造函數UrlModel的唯一原因是UrlModel類已成為測試類的一部分 - 測試類中的代碼本身不可模擬。

想到的另一件事是您可能被調試器誤導了。 當您在分析器運行的情況下創建非抽象類型的模擬時,實例本身與模擬類型具有相同的類型 - 它不是派生類型,例如UrlHelperMock ,就像分析器未運行時的情況一樣。 您能否使用調試器的Make Object ID函數確認模擬實例和從new返回的實例真的不一樣?

你得出的結論是new表達式mocking不起作用,是因為你對UrlHelper的安排不起作用,還是UrlHelper原因?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM