在模拟的HttpContextBase上设置属性

时间:2009-08-04 02:40:17

标签: asp.net-mvc moq

我正在研究一个ASP.NET MVC应用程序,并且正在尝试针对控制器操作编写一些单元测试,其中一些操作处理HttpContext上的属性,例如Session,Request.Cookies,Response.Cookies等。我在弄清楚如何“安排,行动,断言”时遇到了一些麻烦......我可以看到安排和断言......但是我无法弄清楚如何对一个模拟的HttpContextBase的属性进行“行动”其属性只有吸气剂。我无法在我的控制器操作中设置我的模拟上下文中的任何内容...所以它似乎没有用。我很嘲笑,所以我确定有一些我缺少的东西,但我认为我应该能够创建一个模拟对象,我可以在测试控制器操作的上下文中使用实际上可以设置属性值,然后断言它们仍然是我设置它们的东西,或类似的东西。我错过了什么?

    public static HttpContextBase GetMockHttpContext()
    {
        var requestCookies = new Mock<HttpCookieCollection>();
        var request = new Mock<HttpRequestBase>();
        request.Setup(r => r.Cookies).Returns(requestCookies.Object);
        request.Setup(r => r.Url).Returns(new Uri("http://example.org"));

        var responseCookies = new Mock<HttpCookieCollection>();
        var response = new Mock<HttpResponseBase>();
        response.Setup(r => r.Cookies).Returns(responseCookies.Object);

        var context = new Mock<HttpContextBase>();

        context.Setup(ctx => ctx.Request).Returns(request.Object);
        context.Setup(ctx => ctx.Response).Returns(response.Object);
        context.Setup(ctx => ctx.Session).Returns(new Mock<HttpSessionStateBase>().Object);
        context.Setup(ctx => ctx.Server).Returns(new Mock<HttpServerUtilityBase>().Object);
        context.Setup(ctx => ctx.User).Returns(GetMockMembershipUser());
        context.Setup(ctx => ctx.User.Identity).Returns(context.Object.User.Identity);
        context.Setup(ctx => ctx.Response.Output).Returns(new StringWriter());

        return context.Object;
    }

2 个答案:

答案 0 :(得分:4)

不确定是否有人有兴趣,但我已将Moq FakeHttpContext翻译为使用Rhino Mocks(我选择的武器)的一个。

public static HttpContextBase FakeHttpContext()
        {
            var httpContext = MockRepository.GenerateMock<HttpContextBase>();
            var request = MockRepository.GenerateMock<HttpRequestBase>();
            var response = MockRepository.GenerateMock<HttpResponseBase>();
            var session = MockRepository.GenerateMock<HttpSessionStateBase>();
            var server = MockRepository.GenerateMock<HttpServerUtilityBase>();
            var cookies = new HttpCookieCollection();
            response.Stub(r => r.Cookies).Return(cookies);
            request.Stub(r => r.Cookies).Return(cookies);
            request.Stub(r => r.Url).Return(new Uri("http://test.com"));

            httpContext.Stub(x => x.Server).Return(server);
            httpContext.Stub(x => x.Session).Return(session);
            httpContext.Stub(x => x.Request).Return(request);
            httpContext.Stub(x => x.Response).Return(response);
            var writer = new StringWriter();
            var wr = new SimpleWorkerRequest("", "", "", "", writer);
            System.Web.HttpContext.Current = new System.Web.HttpContext(wr);
            return httpContext;

        }

用于

的单元测试
_httpContext = FakeHttpContext();
var cookieManager = new CookieManager(_httpContext);
string username = cookieManager.GetUsername();
_httpContext.AssertWasCalled(hc => { var dummy = hc.Request; });

答案 1 :(得分:2)

嘿,我觉得你刚刚在这里遇到一点脱节,没什么大不了的。你所描述的是100%可能的。

我不完全肯定你为什么不能在Mocks上设置属性,但是如果你发布测试的完整代码,我很乐意和你一起完成它。在我的头顶,我会建议两件事:

  1. Setup()和SetupProperty()之间存在差异。如果你想跟踪属性的值,而不是只从它们获取一次值,那么SetupProperty()可能就是你所追求的。

  2. 或者尝试在需要设置属性的任何模拟上调用SetupAllProperties()。

  3. 查看Moq quickstart以获取一些示例。