代码之家  ›  专栏  ›  技术社区  ›  Geo

如何使用Moq模拟ASP.NET MVC中的HttpContext?

  •  92
  • Geo  · 技术社区  · 16 年前
    [TestMethod]
    public void Home_Message_Display_Unknown_User_when_coockie_does_not_exist()
    {
        var context = new Mock<HttpContextBase>();
        var request = new Mock<HttpRequestBase>();
        context
            .Setup(c => c.Request)
            .Returns(request.Object);
        HomeController controller = new HomeController();
    
        controller.HttpContext = context; //Here I am getting an error (read only).
        ...
     }
    

    我的基本控制器有一个过度的初始化,get就是这个请求上下文。我想把这件事传下去,但我做得不对。

    protected override void Initialize(System.Web.Routing.RequestContext requestContext)
    {
        base.Initialize(requestContext);
    }
    

    在哪里可以获得更多关于使用Moq模拟RequestContext和HttpContext的信息?我试图模仿饼干和一般的上下文。

    5 回复  |  直到 14 年前
        1
  •  60
  •   Sachin Kainth    12 年前

    HttpContext是只读的,但它实际上是从ControllerContext派生的,您可以设置它。

     controller.ControllerContext = new ControllerContext( context.Object, new RouteData(), controller );
    
        2
  •  37
  •   Sklivvz    13 年前

    创建请求、响应并将它们都放到HttpContext:

    HttpRequest httpRequest = new HttpRequest("", "http://mySomething/", "");
    StringWriter stringWriter = new StringWriter();
    HttpResponse httpResponse = new HttpResponse(stringWriter);
    HttpContext httpContextMock = new HttpContext(httpRequest, httpResponse);
    
        3
  •  12
  •   Chandan Kumar    10 年前

    感谢用户010011001001。

    这对我很有用,在为下面的代码编写测试用例时,我遇到了一个问题:

     var currentUrl = Request.Url.AbsoluteUri;
    

    这是解决问题的线

    HomeController controller = new HomeController();
    //Mock Request.Url.AbsoluteUri 
    HttpRequest httpRequest = new HttpRequest("", "http://mySomething", "");
    StringWriter stringWriter = new StringWriter();
    HttpResponse httpResponse = new HttpResponse(stringWriter);
    HttpContext httpContextMock = new HttpContext(httpRequest, httpResponse);
    controller.ControllerContext = new ControllerContext(new HttpContextWrapper(httpContextMock), new RouteData(), controller);
    

    可能对其他人有帮助。

        4
  •  6
  •   Dinis Cruz    11 年前

    下面是一个如何设置的示例: Mocking HttpContext HttpRequest and HttpResponse for UnitTests (using Moq)

    注意那些真正有助于简化模拟类使用的扩展方法:

    var mockHttpContext = new API_Moq_HttpContext();
    
    var httpContext = mockHttpContext.httpContext();
    
    httpContext.request_Write("<html><body>".line()); 
    httpContext.request_Write("   this is a web page".line());  
    httpContext.request_Write("</body></html>"); 
    
    return httpContext.request_Read();
    

    Unit Test for HttpModule using Moq to wrap HttpRequest

    更新:此API已重构为

        5
  •  5
  •   Ria    13 年前

    下面是我如何使用ControllerContext传递一个假的应用程序路径:

    [TestClass]
    public class ClassTest
    {
        private Mock<ControllerContext> mockControllerContext;
        private HomeController sut;
    
        [TestInitialize]
        public void TestInitialize()
        {
            mockControllerContext = new Mock<ControllerContext>();
            sut = new HomeController();
        }
        [TestCleanup]
        public void TestCleanup()
        {
            sut.Dispose();
            mockControllerContext = null;
        }
        [TestMethod]
        public void Index_Should_Return_Default_View()
        {
    
            // Expectations
            mockControllerContext.SetupGet(x => x.HttpContext.Request.ApplicationPath)
                .Returns("/foo.com");
            sut.ControllerContext = mockControllerContext.Object;
    
            // Act
            var failure = sut.Index();
    
            // Assert
            Assert.IsInstanceOfType(failure, typeof(ViewResult), "Index() did not return expected ViewResult.");
        }
    }