C# – ASP.NET MVC unit testing custom AuthorizeAttribute

asp.net-mvccmoqnunitunit testing

I'm working on an ASP.NET MVC 4 project (.NET framework 4) and I was wondering how to properly unit test a custom AuthorizeAttribute (I use NUnit and Moq).

I overrode 2 methods: AuthorizeCore(HttpContextBase httpContext) and HandleUnauthorizedRequest(AuthorizationContext filterContext). As you can see, these methods expect an HttpContextBase and AuthorizationContext respectively, but I don't know how to Mock these.

This is as far as I got:

[Test]
public void HandleUnauthorizedRequest_UnexistingMaster_RedirectsToCommonNoMaster()
{
    // Arrange
    var httpContext = new Mock<HttpContextBase>();
    var winIdentity = new Mock<IIdentity>();
    winIdentity.Setup(i => i.IsAuthenticated).Returns(() => true);
    winIdentity.Setup(i => i.Name).Returns(() => "WHEEEE");
    httpContext.SetupGet(c => c.User).Returns(() => new ImdPrincipal(winIdentity.Object)); // This is my implementation of IIdentity
    var requestBase = new Mock<HttpRequestBase>();
    var headers = new NameValueCollection
        {
           {"Special-Header-Name", "false"}
        };
    requestBase.Setup(x => x.Headers).Returns(headers);
    requestBase.Setup(x => x.HttpMethod).Returns("GET");
    requestBase.Setup(x => x.Url).Returns(new Uri("http://localhost/"));
    requestBase.Setup(x => x.RawUrl).Returns("~/Maintenance/UnExistingMaster");
    requestBase.Setup(x => x.AppRelativeCurrentExecutionFilePath).Returns(() => "~/Maintenance/UnExistingMaster");
    requestBase.Setup(x => x.IsAuthenticated).Returns(() => true);
    httpContext.Setup(x => x.Request).Returns(requestBase.Object);
    var controller = new Mock<ControllerBase>();
    var actionDescriptor = new Mock<ActionDescriptor>();
    var controllerContext = new ControllerContext(httpContext.Object, new RouteData(), controller.Object);

    // Act
    var masterAttr = new ImdMasterAuthorizeAttribute();
    var filterContext = new AuthorizationContext(controllerContext, actionDescriptor.Object);
    masterAttr.OnAuthorization(filterContext);

    // Assert
    Assert.AreEqual("", filterContext.HttpContext.Response);
}

On the line: masterAttr.OnAuthorization(filterContext); a NullReferenceException is thrown. I presume it has something to do with a value in a context we haven't mocked yet.

Any help is greatly appreciated.

Thanks in advance.

Sincerely,
Yanik Ceulemans

Best Answer

Without the code for the attribute one can only guess. But to start investigating, you can create your mocks with MockBehavior.Strict. That way Moq will throw exception when a method or property on the mock are called without previous setup. The exception will have the name of the method/property:

var httpContext = new Mock<HttpContextBase>(MockBehavior.Strict);