I need to create Unit Tests for an ASP.NET MVC 2.0 web site. The site uses Windows Authentication.
I've been reading up on the necessity to mock the HTTP context for code that deals with the HttpContext. I feel like I'm starting to get a handle on the DI pattern as well. (Give the class an attribute of type IRepository and then pass in a Repository object when you instantiate the controller.)
What I don't understand, however, is the proper way to Mock the Windows Principal object available through User.Identity. Is this part of the HttpContext?
Does any body have a link to an article that demonstrates this (or a recommendation for a book)?
Thanks,
Trey Carroll
I've used IoC to abstract this away with some success. I first defined a class to represent the currently logged in user:
public class CurrentUser { public CurrentUser(IIdentity identity) { IsAuthenticated = identity.IsAuthenticated; DisplayName = identity.Name; var formsIdentity = identity as FormsIdentity; if (formsIdentity != null) { UserID = int.Parse(formsIdentity.Ticket.UserData); } } public string DisplayName { get; private set; } public bool IsAuthenticated { get; private set; } public int UserID { get; private set; } }
It takes an IIdentity
in the constructor to set its values. For unit tests, you could add another constructor to allow you bypass the IIdentity
dependency.
And then I use Ninject (pick your favorite IoC container, doesn't matter), and created a binding for IIdentity
as such:
Bind<IIdentity>().ToMethod(c => HttpContext.Current.User.Identity);
Then, inside of my controller I declare the dependency in the constructor:
CurrentUser _currentUser; public HomeController(CurrentUser currentUser) { _currentUser = currentUser; }
The IoC container sees that HomeController
takes a CurrentUser
object, and the CurrentUser
constructor takes an IIdentity
. It will resolve the dependencies automatically, and voila! Your controller can know who the currently logged on user is. It seems to work pretty well for me with FormsAuthentication. You might be able to adapt this example to Windows Authentication.
I don't know for MVC 2.0, but in newer versions you can mock the ControllerContext:
// create mock principal var mocks = new MockRepository(MockBehavior.Default); Mock<IPrincipal> mockPrincipal = mocks.Create<IPrincipal>(); mockPrincipal.SetupGet(p => p.Identity.Name).Returns(userName); mockPrincipal.Setup(p => p.IsInRole("User")).Returns(true); // create mock controller context var mockContext = new Mock<ControllerContext>(); mockContext.SetupGet(p => p.HttpContext.User).Returns(mockPrincipal.Object); mockContext.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(true); // create controller var controller = new MvcController() { ControllerContext = mock.Object };
see also How to unit-test an MVC controller action which depends on authentification in c#?
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