[英]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.