RSS

Tag Archives: moq

Unit Testing WIF’s ClaimsPrincipalPermission.CheckAccess

WIF 4.5 has ClaimsPrincipalPermission.CheckAccess method, very useful to check user’s authorization. You can use this as method call or attribute.

// Imperative method call
using System.IdentityModel.Services;
public ActionResult Index()
{
    ClaimsPrincipalPermission.CheckAccess("foo", "bar");

    return View();
}

// Attribute
[ClaimsPrincipalPermission(SecurityAction.Demand, Operation="foo", Resource="bar")]
public ActionResult ViewFoobar()
{
    return View();
}

Either way, how do we unit test this? My approach is to first abstract out ClaimsPrincipalPermission and create a new wrapper class that will be injected to the dependent class.

Abstract Out

using System.IdentityModel.Services;

public class ClaimsPrincipalWrapper : IClaimsPrincipalWrapper
{
    public void CheckAccess(string resource, string action)
    {
        ClaimsPrincipalPermission.CheckAccess(resource, action);
    }
}

Dependency Injection

using System.IdentityModel.Services;

public class HomeController : Controller
{
    private readonly IClaimsPrincipalWrapper _ClaimsPrincipalWrapper;

    public HomeController(IClaimsPrincipalWrapper claimsPrincipalWrapper)
    {
        _ClaimsPrincipalWrapper = claimsPrincipalWrapper;
    }

    public ActionResult Index()
    {
        _ClaimsPrincipalWrapper.CheckAccess("foo", "bar");

        return View();
    }
}

Unit Test

[TestMethod]
public void TestIndex()
{
    // Arrange
    var _claimsPrincipal = new Mock<IClaimsPrincipalWrapper>();
    _claimsPrincipal.Setup(m => m.CheckAccess(It.IsAny<string>, It.IsAny<string>));
    var _controller = new HomeController(_claimsPrincipalMock.Object);

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

    // Assert
    Assert.IsTrue(_result.View != null);
}
Advertisements
 
Leave a comment

Posted by on May 4, 2015 in General

 

Tags: , , , , , , ,

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

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,

 
1 Comment

Posted by on August 15, 2014 in General

 

Tags: , ,

 
%d bloggers like this: