在justmock中,我们可以通过像
那样排列构造函数调用来返回模拟实例而不是实际实例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 :(得分: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);
}
答案 1 :(得分:0)
您正在UrlHelper
的构造函数中手动实例化UrlModel
的实例。 UrlModel
现已紧密耦合到UrlHelper
( new is 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 ..
}
答案 2 :(得分:0)
在这种情况下构造函数模拟不起作用的唯一原因是UrlModel
类已成为测试类的一部分 - 测试类中的代码本身不可模仿。
我想到的另一件事是你可能被调试器误导了。在运行探查器的情况下创建非抽象类型的模拟时,实例本身与模拟类型的类型相同 - 它不是派生类型,比如UrlHelperMock
,因为它是分析器未运行时的情况。您能否使用调试器Make Object ID
函数确认模拟实例和从new
返回的实例真的不一样?
您是否得出结论new
表达式嘲弄不起作用,因为您UrlHelper
的安排不起作用,或者是其他内容?