Monday, August 25, 2014

Mocking HttpContext and it's dependencies

If your controllers access HttpSession or any other dependencies within the HttpContext then you wont be able to write tests for that controller unless you're able to mock HttpContext.

Asp.Net MVC provides the abstract HttpContextBase class which represents the dependencies within HttpContext as virtual properties that are mockable using a mocking framework such as Moq.

I have written the following class which is a helper that allows for the mocked HttpContext to return a default set of mocked dependencies but it also allows you to override those dependencies and set them up according to the scenario being exercised in your tests.

using System.Security.Principal;
using System.Web;
using Moq;

namespace UnitTests.Helpers
{
    public class FakeHttpContext
    {
        private static Mock<HttpSessionStateBase> _session;
        public static Mock<HttpSessionStateBase> Session
        {
            get { return _session ?? (_session = new Mock<HttpSessionStateBase>()); }
            set { _session = value; }
        }

        private static Mock<HttpRequestBase> _request;
        public static Mock<HttpRequestBase> Request
        {
            get
            {
                if (_request != null) return _request;
                _request = new Mock<HttpRequestBase>();
                _request.Setup(req => req.ApplicationPath).Returns("/");
                _request.Setup(req => req.AppRelativeCurrentExecutionFilePath).Returns("~/");
                _request.Setup(req => req.PathInfo).Returns(string.Empty);
                return _request;
            }

            set { _request = value; }
        }

        private static Mock<HttpResponseBase> _response;
        public static Mock<HttpResponseBase> Response
        {
            get{return _response ?? (new Mock<HttpResponseBase>());}
            set { _response = value; }
        }
        
        private static Mock<HttpServerUtilityBase> _server;
        public static Mock<HttpServerUtilityBase> Server
        {
            get
            { return _server ?? (new Mock<HttpServerUtilityBase>()); }
            set { _server = value; }
        }

        private static Mock<IPrincipal> _user;
        public static Mock<IPrincipal> User
        {
            get
            { return _user ?? (new Mock<IPrincipal>()); }
            set { _user = value; }
        }

        private static Mock<IIdentity> _identity;
        public static Mock<IIdentity> Identity
        {
            get
            { return _identity ?? (new Mock<IIdentity>()); }
            set { _identity = value; }
        }


        public static HttpContextBase Context
        {
            get
            {
                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(Session.Object);
                context.Setup(ctx => ctx.Server).Returns(Server.Object);

                //bind identity to _user
                User.Setup(usr => usr.Identity).Returns(Identity.Object);

                context.Setup(ctx => ctx.User).Returns(User.Object);
                return context.Object;
            }
        }
            
    }
}

No comments :

Post a Comment