Asp – Setting properties on a mocked HttpContextBase

asp.net-mvcmoq

I'm working on an ASP.NET MVC application, and am trying to write some unit tests against controller actions, some of which manipulate properties on the HttpContext, such as Session, Request.Cookies, Response.Cookies, etc. I'm having some trouble figuring out how to "Arrange, Act, Assert"…I can see Arrange and Assert…but I'm having trouble figuring out how to "Act" on properties of a mocked HttpContextBase when all of its properties only have getters. I can't set anything on my mocked context from within my controller actions…so it doesn't seem very useful. I'm fairly new to mocking, so I'm sure there's something that I'm missing, but it seems logical to me that I should be able to create a mock object that I can use in the context of testing controller actions where I can actually set property values, and then later Assert that they're still what I set them to, or something like that. What am I missing?

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

Best Answer

Hey, I think you're just experiencing a bit of a disconnect here, no big deal. What you describe is 100% possible.

I'm not entirely positive on why you can't set properties on your Mocks, but if you post the full code for your test I'd be happy to go through it with you. Just off the top of my head, I'll suggest two things:

  1. There is a difference between Setup() and SetupProperty(). SetupProperty() is probably what you're after if you want to track values on properties, rather than just get a value from them once.

  2. Alternately try calling SetupAllProperties() on any mock that you need to set a property on.

Check the Moq quickstart as well for some examples.

Related Topic