在Justmock中对UrlHelper的mock构造函数调用失败
本文关键字:函数调用 失败 mock Justmock 中对 UrlHelper | 更新日期: 2023-09-27 18:09:33
在justmock中,我们可以通过安排构造函数调用来返回模拟实例而不是实际实例,如
Mock.Arragne(()=>new MyClass(Arg.IsAny<string>())).IgnoreInstance().Returns(Mock.Create<MyClass>());
但是当我尝试与UrlHelper
类相同时,而不是模拟类型,实际类型正在实例化。谁能告诉我这里是否有错误?
UrlModel class
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 ..
}
在这种情况下构造函数mock不能工作的唯一原因是UrlModel
类是测试类的一部分——测试类中的代码本身是不可mock的。
想到的另一件事是,您可能被调试器误导了。当您在运行剖析器的情况下创建非抽象类型的模拟时,实例本身的类型与模拟类型相同—它不是派生类型,例如UrlHelperMock
,这是剖析器未运行时的情况。您可以使用调试器Make Object ID
函数确认模拟实例和从new
返回的实例确实不一样吗?
你得出的结论是,new
的表达嘲讽不起作用,因为你的UrlHelper
的安排不起作用,或者是别的什么?