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
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With