RSS

ASP.Net MVC Unit Test Controller with HttpContext (ControllerContext)

15 Aug

Often time, I have MVC Controller that access ControllerContext, so my unit test for the controller will have to mock this.

I create 2 files: MockHttpSession.cs and Helpers.cs

MockHttpSession.cs is just mocking HttpSession by create a Dictionary to store object. Moq framework that I use won’t be able to mock HttpSession, so I have to create my own.

Helpers.cs has methods to mock ControllerContext, HttpContext, HttpResponseBase, HttpRequestBase, ClaimsPrincipal, and ClaimsIdentity. You can pass in custom object in the parameter, otherwise, it will use the default.

MockHttpSession.cs

class MockHttpSession : HttpSessionStateBase
{
    readonly Dictionary<string, object> _SessionDictionary = new Dictionary<string, object>();
    public override object this[string name]
    {
        get
        {
            object obj = null;
            _SessionDictionary.TryGetValue(name, out obj);
            return obj;
        }
        set { _SessionDictionary[name] = value; }
    }
}

Helpers.cs

class Helpers
{
    internal static Mock<ControllerContext> GetMvcControllerContextMock(HttpContextBase httpContextBase = null)
    {
        // Set default HttpContextBase
        if (httpContextBase == null)
            httpContextBase = GetHttpContextMock().Object;

        var _controllerContextMock = new Mock<ControllerContext>();

        // Add default HttpContextBase
        _controllerContextMock.Setup(x => x.HttpContext).Returns(httpContextBase);

        return _controllerContextMock;
    }

    internal static Mock<HttpContextBase> GetHttpContextMock(ClaimsPrincipal claimsPrincipal = null, ClaimsIdentity claimsIdentity = null, HttpResponseBase httpResponseBase = null, HttpRequestBase httpRequestBase = null)
    {
        var _httpContextMock = new Mock<HttpContextBase>();

        // Set default ClaimsIdentity
        if (claimsIdentity == null)
            claimsIdentity = GetClaimsIdentityMock().Object;

        // Set default ClaimsPrincipal
        if (claimsPrincipal == null)
            claimsPrincipal = GetClaimsPrincipalMock(claimsIdentity).Object;

        // Set default HttpContextBase
        if (httpResponseBase == null)
            httpResponseBase = GetHttpResponseBaseMock().Object;
        if (httpRequestBase == null)
            httpRequestBase = GetHttpRequestBaseMock().Object;

        // Add Session object to HttpContext
        var _session = new MockHttpSession();

        // Add ClaimsPrincipal to HttpContext.User
        _httpContextMock.Setup(x => x.User).Returns(claimsPrincipal);

        // Add UserClaims to HttpContext.Session
        _httpContextMock.Setup(x => x.Session).Returns(_session);

        // Add HttpContextBase object to HttpContext
        _httpContextMock.Setup(x => x.Response).Returns(httpResponseBase);

        _httpContextMock.Setup(x => x.Request).Returns(httpRequestBase);
        return _httpContextMock;
    }

    internal static Mock<HttpResponseBase> GetHttpResponseBaseMock(int? statusCode = 0)
    {
        var _httpResponseMock = new Mock<HttpResponseBase>();

        // Set default StatusCode
        if (statusCode == null)
            statusCode = (int) HttpStatusCode.OK;

        // Add StatusCode to HttpResponse.StatusCode
        _httpResponseMock.Setup(x => x.StatusCode).Returns(statusCode.Value);

        return _httpResponseMock;
    }

    internal static Mock<HttpRequestBase> GetHttpRequestBaseMock()
    {
        var _httpRequestMock = new Mock<HttpRequestBase>();

        // Add StatusCode to HttpResponse.StatusCode
        _httpRequestMock.Setup(x => x.QueryString).Returns(new NameValueCollection());
        _httpRequestMock.Setup(x => x.AppRelativeCurrentExecutionFilePath).Returns(string.Empty);
        _httpRequestMock.Setup(x => x.PathInfo).Returns(string.Empty);
        _httpRequestMock.Setup(x => x.Url).Returns(new Uri("http://site/"));
        return _httpRequestMock;
    }

    internal static Mock<ClaimsPrincipal> GetClaimsPrincipalMock(ClaimsIdentity identity = null)
    {
        // Set default ClaimsIdentity
        if (identity == null)
            identity = GetClaimsIdentityMock().Object;

        var _principalMock = new Mock<ClaimsPrincipal>();
        _principalMock.Setup(x => x.Identity).Returns(identity);

        return _principalMock;
    }

    internal static Mock<ClaimsIdentity> GetClaimsIdentityMock(List<Claim> claimCollection = null, bool isAuthenticated = true)
    {
        // Set default ClaimCollection
        if (claimCollection == null)
        {
            claimCollection = new List<Claim>();
            //claimCollection.AddRange(Models.ValidClaims);
        }

        var _identityMock = new Mock<ClaimsIdentity>();
        _identityMock.Setup(x => x.IsAuthenticated).Returns(isAuthenticated);
        _identityMock.Setup(x => x.Claims).Returns(claimCollection);

        return _identityMock;
    }
}

Usage

[TestMethod]
public void Index_Get_ViewNotNull()
{
    // Arrange
    var _controller = new OrderController();
    _controller.ControllerContext = Helpers.GetMvcControllerContextMock(Helpers.GetHttpContextMock().Object).Object;

    // Act
    var _result = _controller.Index() as ViewResult;

    // Assert
    Assert.IsNotNull(_result);
}

Version attow: ASP.Net MVC 5, Moq 4.1,

Advertisements
 
1 Comment

Posted by on August 15, 2014 in General

 

Tags: , ,

One response to “ASP.Net MVC Unit Test Controller with HttpContext (ControllerContext)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

 
%d bloggers like this: