我似乎无法使用Moq来模拟HttpContext.Request.Url.Authority
,因为它是一个非虚拟方法。我收到以下异常:
{"Invalid setup on a non-virtual (overridable in VB) member: p => p.HttpContext.Request.Url.Authority"}
我该如何克服这个问题?以下是我的测试方法:
[TestMethod]
public void ForgottenPasswordPost_Requested_CaptchaCorrectEmailExists()
{
_testModel.ControllerContext.SetupGet(p => p.HttpContext.Session["Captcha"]).Returns("HelloWorld");
_testModel.ControllerContext.SetupGet(p => p.HttpContext.Request.Url.Authority).Returns("www.localhost.com");
_testModel.QMember.Setup(m => m.MemberExistsWithEmail(It.IsAny<string>())).Returns(true);
var controllerUnderTest = _testModel.ReturnController();
ForgottenPasswordModel model = new ForgottenPasswordModel() { Captcha = "HelloWorld" };
//Act
var actionResult = (RedirectToRouteResult)controllerUnderTest.ForgottenPassword(model);
Assert.AreEqual("ForgottenPasswordConfirm", actionResult.RouteValues["action"]);
Assert.AreEqual("a", actionResult.RouteValues["controller"]);
}
public class TestModel
{
public UnregisteredController Controller { get; set; }
public Mock<ControllerContext> ControllerContext { get; set; }
public Mock<IQ_Member> QMember { get; set; }
public TestModel()
{
ControllerContext = new Mock<ControllerContext>();
QMember = new Mock<IQ_Member>();
}
public UnregisteredController ReturnController()
{
Controller = new UnregisteredController(QMember.Object);
Controller.ControllerContext = ControllerContext.Object;
return Controller;
}
}
最佳答案
根据this SO post ,您只能使用 Moq 来实现虚拟/抽象成员。
在一般的非 ASP.NET MVC 情况下,您可以
使用允许覆盖非虚拟、具体类成员的模拟工具或
使用静态/非虚拟成员的传递方法编写自己的包装类,从这些包装类中提取接口(interface),然后设计其余的代码以依赖于这些接口(interface),这样就可以轻松地被 mock 并注入(inject)依赖。
我会推荐#2而不是上面的#1,尽管它会导致相当多的工作量,因为#2几乎肯定会导致代码更好地遵守 Dependency Inversion principle .
但是,就您的情况而言,我认为有一个相当简单的解决方案。
在代码行
_testModel.ControllerContext.SetupGet(p => p.HttpContext.Request.Url.Authority).Returns("www.localhost.com");
.HttpContext
是抽象的,因此可以模拟.Request
是抽象的,因此可以模拟.Url
是虚拟的,因此可以模拟.Authority
是一个非虚拟字符串属性,这就是给您带来问题的原因
试试这个,因为 .Url
是您可以模拟的最深部分:
_testModel.ControllerContext.SetupGet(p => p.HttpContext.Request.Url).Returns(new Uri("http://www.localhost.com"));
关于asp.net-mvc - Moq - 如何模拟 HttpContext.Request.Url.Authority 对象等非虚拟成员?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14461874/