当前位置:编程学习 > asp >>

测试MVC之Mock HttpContext

 

在Web 中进行测试驱动的开发,比较大的困难是模拟HttpContext ,它太复杂了。

moq 框架提供了强大的模拟能力,但是,模拟一个HttpContext 对象还是需要自己来动手。

为此,我自己写了一个方法来完成这个工作。其中,还顺便使用Log4Net 来输出一下它的工作情况。

view sourceprint?

01    /// <summary>

02    /// 创建上下文模拟对象 

03    /// 至少需要支持

04    ///     Request 中

05    ///         AppRelativeCurrentExecutionFilePath,

06    ///         ApplicationPath

07    ///         PathInfo

08    ///     Response 中

09    ///         ApplyAppPathModifier

10    /// </summary>

11    /// <returns></returns>

12    private Moq.Mock<System.Web.HttpContextBase> CreateHttpContext()

13    {

14        log4net.ILog log = log4net.LogManager.GetLogger("CreateHttpContext");

15     

16        string ApplicationPath = "/";

17        string PathInfo = "";

18        string AppRelativeCurrentExecutionFilePath = "~/";

19     

20        var contextMock = new Moq.Mock<System.Web.HttpContextBase>();

21     

22        contextMock

23            .Setup(c => c.Request.AppRelativeCurrentExecutionFilePath)

24            .Returns(AppRelativeCurrentExecutionFilePath)

25            .Callback(() => log.Info("Calling AppRelativeCurrentExecutionFilePath"));

26     

27        contextMock

28            .Setup(c => c.Request.ApplicationPath)

29            .Returns(ApplicationPath)

30            .Callback(() => log.Info("Calling ApplicationPath"));

31        contextMock.Setup(rc => rc.Request.PathInfo)

32            .Returns(PathInfo)

33            .Callback(() => log.Info("Calling PathInfo"));

34     

35        contextMock

36            .Setup(rc => rc.Response.ApplyAppPathModifier(Moq.It.IsAny<string>()))

37            .Returns((string s) => s)

38            .Callback((string s) => log.InfoFormat("Calling ApplyAppPathModifier: {0}.", s));

39     

40        return contextMock;

41    }

虽然这个方法已经能够完成我需要的测试,但是,我希望能将它提炼一下,得到一个更加通用的Mock 方法。

很快,我发现这个工作已经在很久以前被Scott Hanselman 介绍过一次了,其中甚至还写了不同的Mock 框架下的提供方法。不过moq 版本的作者不是他,而是另外一个人Daniel Cazzulino, 这篇文章你可以在这里找到:http://www.hanselman.com/blog/ASPNETMVCSessionAtMix08TDDAndMvcMockHelpers.aspx,还可以顺便看一下Daniel Cazzulino 的博客:http://blogs.clariusconsulting.net/kzu/

不过,他的文章是在2008 年写的,实在太古老了。当时还是MVC 的Preview2 ,moq 在那个时候就已经诞生了,看来我太孤陋寡闻了。

回到我们的主题,经过了这么长的时间,moq 已经有了一些变化,使用最新的moq 语法修改之后,发现他的的代码没有能够通过测试。

与我的比较一下,发现其中少了对Response 中ApplyAppPathModifier 方法的支持,增加之后就正常了。

下面是修改之后的代码,希望能给你带来方便。

view sourceprint?

001  using System;

002  using System.Web;

003  using System.Text.RegularExpressions;

004  using System.IO;

005  using System.Collections.Specialized;

006  using System.Web.Mvc;

007  using System.Web.Routing;

008   

009  using Moq;

010   

011  namespace UnitTests

012  {

013      public static class MvcMockHelpers

014      {

015          public static HttpContextBase FakeHttpContext()

016          {

017              var context = new Mock<HttpContextBase>();

018              var request = new Mock<HttpRequestBase>();

019              var response = new Mock<HttpResponseBase>();

020              var session = new Mock<HttpSessionStateBase>();

021              var server = new Mock<HttpServerUtilityBase>();

022   

023              // 必须要设置Response 的ApplyAppPathModifier 方法支持

024              response

025                  .Setup(rsp => rsp.ApplyAppPathModifier(Moq.It.IsAny<string>()))

026                  .Returns((string s) => s);

027                   

028              context.Setup(ctx => ctx.Request).Returns(request.Object);

029              context.Setup(ctx => ctx.Response).Returns(response.Object);

030              context.Setup(ctx => ctx.Session).Returns(session.Object);

031              context.Setup(ctx => ctx.Server).Returns(server.Object);

032   

033              return context.Object;

034          }

035   

036          public static HttpContextBase FakeHttpContext(string url)

037          {

038              HttpContextBase context = FakeHttpContext();

039  &

补充:Web开发 , ASP.Net ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,