In ASP.Net, there is a concept of an identity. Built on top of this is an authentication system based on claims; allowing applications to implement a claims based authentication system. That is, I can determine if my user has “Administrator” privileges in the following syntax:
var claim = ClaimsIdentity.FindFirstValue("Administrator");
For more information about how claims work, see this excellent explanation. This post is not really concerned with how claims work, but rather, how to mock them out; which is much more difficult than you might guess.
In the references below, you’ll see a number of different strategies to mock out the claims and principle objects. There also seems to be a loose consensus that even attempting to do this is folly. However, I’ve cobbled together a set of mocks using NSubstitute that work. I’m not claiming that they work in all cases, or that they will work in any situation other than the specific one that I am trying to solve; but it did work for that, and so I thought it useful enough to share.
var myController = new MyController();
var mockClaim = new Claim("Administrator", "test");
var identity = Substitute.For<ClaimsIdentity>();
identity.Name.Returns("test");
identity.IsAuthenticated.Returns(true);
identity.FindFirst(Arg.Any<string>()).Returns(mockClaim);
var claimsPrincipal = Substitute.For<ClaimsPrincipal>();
claimsPrincipal.HasClaim(Arg.Any<string>(), Arg.Any<string>()).Returns(true);
claimsPrincipal.HasClaim(Arg.Any<Predicate<Claim>>()).Returns(true);
claimsPrincipal.Identity.Returns(identity);
var httpContext = Substitute.For<HttpContextBase>();
httpContext.User.Returns(claimsPrincipal);
var controllerContext = new ControllerContext(
httpContext, new System.Web.Routing.RouteData(), myController);
myController.ControllerContext = controllerContext;
// Act
var result = myController.TestMethod();
// Assert
// . . .
Remember that this is only necessary if you are trying to access claims based on the identity within the `TestMethod()`. Also, I’ll remind the reader that I assert only that this worked in the specific situation that I needed it to, but it’s probably a good starting point for others.
References
https://volaresystems.com/blog/post/2010/08/19/Dont-mock-HttpContext
http://nsubstitute.github.io/help/set-return-value/
https://stackoverflow.com/questions/1389744/testing-controller-action-that-uses-user-identity-name
https://stackoverflow.com/questions/13579519/mock-authenticated-user-using-moq-in-unit-testing
https://stackoverflow.com/questions/22762338/how-do-i-mock-user-identity-getuserid/23960592
https://dotnetcodr.com/2013/02/11/introduction-to-claims-based-security-in-net4-5-with-c-part-1/