2009-09-21 110 views
87
[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). 
    ... 
} 

我的基本控制器具有初始化得到的这个的RequestContext的overrride。我试图通过这一点,但我没有做正确的事情。如何使用Moq模拟ASP.NET MVC中的HttpContext?

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

从哪里可以获得更多关于使用Moq来模拟我的RequestContext和HttpContext的信息?我试图嘲笑饼干和一般情况。

回答

52

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

controller.ControllerContext = new ControllerContext(context.Object, new RouteData(), controller); 
+0

这一个允许我设置一个模拟的HttpContext控制器上为我工作。 – 2012-05-14 12:22:09

32

创建一个请求,响应,并把他们两个的HttpContext:

HttpRequest httpRequest = new HttpRequest("", "http://mySomething/", ""); 
StringWriter stringWriter = new StringWriter(); 
HttpResponse httpResponse = new HttpResponse(stringWriter); 
HttpContext httpContextMock = new HttpContext(httpRequest, httpResponse); 
+0

的问题是关于*基类,即HttpRequestBase,不HttpRequest的 - 不知道为什么两者都需要自己,更讨厌的是他们是“密封”。没有办法设置LogonUserIdentity :( – 2010-10-22 08:57:36

+0

如果他们整理我的参考,它仍然通过远程可能的,所以它不应该是一个问题 – 0100110010101 2010-10-22 11:46:40

+1

@ChrisKimpton:作为最后的手段,总是有_reflection_ ;-) – Oliver 2014-01-15 16:57:37

5

这里是你如何设置此了一个例子: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(); 

这里是一个例子如何用最小起订量检查一个HttpModule按预期工作写单元测试:Unit Test for HttpModule using Moq to wrap HttpRequest

更新:这个API已经被重构为

3

以下是我使用的ControllerContext传递一个假的应用轻拍H:

[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."); 
    } 
} 
+1

为什么你需要通过一个虚假的应用程序路径? – 2011-11-10 19:30:59

+0

MVC代码将执行它并抛出一个空异常,如果它不存在。 – 2013-01-15 16:29:19

7

感谢用户0100110010101.

它为我在这里一边写测试用例为下面的代码我有一个问题:

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

可能对其他人有帮助。

相关问题