【问题标题】:Unit testing in asp.net MVC, how do I mock a page request?asp.net MVC中的单元测试,如何模拟页面请求?
【发布时间】:2009-04-21 19:26:58
【问题描述】:

如何模拟 .net MVC 页面的页面请求?

【问题讨论】:

    标签: asp.net-mvc unit-testing mocking


    【解决方案1】:

    使用 RhinoMocks:

     var httpContext = MockRepository.GenerateMock<HttpContextBase>();
     var httpRequest = MockRepository.GenerateMock<HttpRequestBase>();
    
     httpContext.Expect( c => c.Request ).Return( httpRequest ).Repeat.Any();
    
     ... set up expectations on request...
    
     var controller = new MyController();
     controller.ControllerContext = new ControllerContext( httpContext,
                                                           new RouteData(),
                                                           controller );
    
     ...invoke action, check assertions...
    
     httpContext.VerifyAllExpectations();
     httpRequest.VerifyAllExpectations();
    

    【讨论】:

      【解决方案2】:

      使用Moq

      var request = new Mock<HttpRequestBase>(MockBehavior.Strict);
      request.Setup(x => x.ApplicationPath).Returns("/");
      request.Setup(x => x.Url).Returns(new Uri("http://localhost/home"));
      request.Setup(x => x.ServerVariables).Returns(new System.Collections.Specialized.NameValueCollection());
      
      var context = new Mock<HttpContextBase>(MockBehavior.Strict);
      context.SetupGet(x => x.Request).Returns(request.Object);
      
      var controller = new YourController();
      controller.ControllerContext = new ControllerContext(context.Object, new RouteData(), controller);
      

      【讨论】:

        【解决方案3】:

        手动(因为我讨厌每次测试需要 8 行设置的 Mocking 框架)

        // in some common location, only once
        public class MockHttpContext : HttpContextBase
        {
            public MockHttpRequest m_request = new MockHttpRequest();
            public MockHttpResponse m_response = new MockHttpResponse();
        
            public override HttpRequestBase Request
            { get { return m_request; } }
        
            public override HttpResponseBase Response
            { get { return m_response; } }
        }
        
        public class MockHttpRequest : HttpRequestBase
        {
            // override whatever bits you want (eg cookies)
        }
        
        public class MockHttpResponse : HttpResponseBase
        {
            // override whatever bits you want (eg cookies)
        }
        
        // in your specific test
        controller = new YourController {
            ControllerContext = new ControllerContext { HttpContext = new MockHttpContext() }
        };
        

        【讨论】:

        • 我喜欢这个。这比嘲笑要容易理解得多。 m_request 和 m_response 公开的任何原因?
        • 因为它是一个假对象,旨在简化测试。将它们设为私有仅意味着如果我想更改它们(有时您可能会),我必须拥有一个属性等。一些规则(例如实现隐藏)在这种环境中是非常有害的
        • 在我提出这个问题后,我才意识到为什么它们是公开的。 Request 和 Response 都没有设置器,因为它在 HttpContextBase 中就是这样。因此,如果我需要改变单元测试中的请求和响应,我需要将它们公开。
        • @OrionEdwards,这是我能找到的唯一答案,它解释了如何在不模拟框架的情况下进行这种简单的思考。它必须内置到 ASP.NET MVC 中,因为单元测试是该框架带来的主要优势之一。这很容易。可惜几乎没有人谈论它。非常感谢!!
        猜你喜欢
        • 1970-01-01
        • 2013-12-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-01-26
        • 1970-01-01
        • 2010-10-13
        • 1970-01-01
        相关资源
        最近更新 更多