Skip to content

Moq and MvcMockHelpers

I’m working on some unit tests for an ASP.NET MVC application I’m developing.  One of the tests ensures that if I construct a URL using Html.ActionLink that the URL which is returned, when fed into the routing system, becomes a correct representation of the route data used to build the URL originally.  I’ll discuss this further in a future post, but today I’m going to talk about Moq. Unfortunately, this type of testing requires more mocking than you’d really prefer, despite the significant improvements in unit-testability in recent previews of the ASP.NET MVC framework.

I started with the MvcMockHelpers library released by Scott Haselman.  It does quite a bit of what I need, so that saved me a lot of work.  Scott’s library supports three different mocking frameworks; of these, I chose Moq.

My tests hit some areas of the HttpContext which Scott’s mock didn’t implement, so I set out to extend it.  One bit, HttpContextBase.ApplyAppPathModifier, was a bit more challenging to mock, despite the fact that the result I needed was quite simple: The mocked function should simply return its only argument.  The Moq demos don’t cover this case, although it is a supported feature in the 2.0 version. After a little digging around through the forums and the change logs, I figured out how to do it:

response.Expect(res => res.ApplyAppPathModifier(It.IsAny<string>()))
    .Returns((string virtualPath) => virtualPath);

There are two parts to this.  First, you specify that this mock will match a call to ApplyAppPathModifier with any string argument.  That is the It.IsAny bit.  Inside the Returns call is a lambda expression which specifies how to turn a string argument into a result.  In this case, the expression is very simple.

So, for anyone who wants it, here is my current implementation of the FakeHttpContext() method.  It returns a mocked HttpContext which is good enough for the unit testing I’m doing at the moment.

        public static HttpContextBase FakeHttpContext()
        {
            var context = new Mock<HttpContextBase>();
            var request = new Mock<HttpRequestBase>();
            var response = new Mock<HttpResponseBase>();
            var session = new Mock<HttpSessionStateBase>();
            var server = new Mock<HttpServerUtilityBase>();
            var user = new Mock<IPrincipal>();
            var identity = new Mock<IIdentity>();

            request.Expect(req => req.ApplicationPath).Returns("~/");
            request.Expect(req => req.AppRelativeCurrentExecutionFilePath).Returns("~/");
            request.Expect(req => req.PathInfo).Returns(string.Empty);
            response.Expect(res => res.ApplyAppPathModifier(It.IsAny<string>()))
                .Returns((string virtualPath) => virtualPath);
            user.Expect(usr => usr.Identity).Returns(identity.Object);
            identity.ExpectGet(ident => ident.IsAuthenticated).Returns(true);

            context.Expect(ctx => ctx.Request).Returns(request.Object);
            context.Expect(ctx => ctx.Response).Returns(response.Object);
            context.Expect(ctx => ctx.Session).Returns(session.Object);
            context.Expect(ctx => ctx.Server).Returns(server.Object);
            context.Expect(ctx => ctx.User).Returns(user.Object);

            return context.Object;
        }

{ 1 } Trackback

  1. [...] to web applications which I don’t need for the unit test.  So I use the Moq framework and a mocked context which I posted earlier.  In general, to create a mock of a certain type using Moq, you [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *

Bad Behavior has blocked 713 access attempts in the last 7 days.

Close