Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/magento/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc Moq-如何模拟HttpContext.Request.Url.Authority对象这样的非虚拟成员?_Asp.net Mvc_Tdd_Moq - Fatal编程技术网

Asp.net mvc Moq-如何模拟HttpContext.Request.Url.Authority对象这样的非虚拟成员?

Asp.net mvc Moq-如何模拟HttpContext.Request.Url.Authority对象这样的非虚拟成员?,asp.net-mvc,tdd,moq,Asp.net Mvc,Tdd,Moq,我似乎不能使用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_Re

我似乎不能使用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;
    }
}
[TestMethod]
public void ForgottenPasswordPost\u请求的\u captchacorrectiveEmailExists()
{
_testModel.ControllerContext.SetupGet(p=>p.HttpContext.Session[“Captcha”)。返回(“HelloWorld”);
_testModel.ControllerContext.SetupGet(p=>p.HttpContext.Request.Url.Authority).Returns(“www.localhost.com”);
_testModel.QMember.Setup(m=>m.MemberExistsWithEmail(It.IsAny())。返回(true);
var controllerUnderTest=_testModel.ReturnController();
ForgottenPasswordModel=新ForgottenPasswordModel(){Captcha=“HelloWorld”};
//表演
var actionResult=(RedirectToRouteResult)controllerUnderTest.ForgottenPassword(模型);
AreEqual(“ForgottenPasswordConfirm”,actionResult.RouteValues[“action”]);
Assert.AreEqual(“a”,actionResult.RouteValues[“controller]”);
}
公共类测试模型
{
公共未注册控制器控制器{get;set;}
公共模拟控制器上下文{get;set;}
公共模拟QMember{get;set;}
公共测试模型()
{
ControllerContext=新建模拟();
QMember=newmock();
}
公共未注册控制器ReturnController()
{
控制器=新的未注册控制器(QMember.Object);
Controller.ControllerContext=ControllerContext.Object;
返回控制器;
}
}
根据,只能使用Moq实现虚拟/抽象成员

在一般的非ASP.NET MVC情况下,您可以

  • 使用模拟工具,允许重写非虚拟、具体的类成员或

  • 使用传递方法编写自己的包装器类到静态/非虚拟成员,从这些包装器类中提取接口,然后将代码的其余部分设计为依赖于这些接口,这些接口可以很容易地模拟和注入依赖关系

  • 我会推荐上面的#2胜过#1,尽管它会导致相当多的工作,因为#2几乎肯定会导致代码更好地遵守规则

    然而,在你的情况下,我认为有一个相当简单的解决办法

    在代码行中

    _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"));
    
    根据,您只能使用Moq实现虚拟/抽象成员

    在一般的非ASP.NET MVC情况下,您可以

  • 使用模拟工具,允许重写非虚拟、具体的类成员或

  • 使用传递方法编写自己的包装器类到静态/非虚拟成员,从这些包装器类中提取接口,然后将代码的其余部分设计为依赖于这些接口,这些接口可以很容易地模拟和注入依赖关系

  • 我会推荐上面的#2胜过#1,尽管它会导致相当多的工作,因为#2几乎肯定会导致代码更好地遵守规则

    然而,在你的情况下,我认为有一个相当简单的解决办法

    在代码行中

    _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"));