views:

2009

answers:

4

I'm trying to unit test a piece of code that needs a currently logged in user in the test. Using the .Net 2.0 Membership Provider, how can I programmatically log in as a user for this test?

A: 

Does your code actually need a user logged in via ASP.NET, or does it just need a CurrentPrincipal? I don't think you need to programmatically log in to your site. You can create a GenericPrincipal, set the properties you need, and attach it to, for example Thread.CurrentPrincipal or a mocked HttpContext. If your code actually needs RolePrincipal or something then I would change the code to be less coupled to ASP.NET membership.

Craig Stuntz
I need the call to Membership.GetUser() to return the currently logged in user.
ddc0660
Don't call Membership.GetUser() directly in the class under test. Supply the class with an IGetUser in creation, use it in place of Membership.GetUser(), then make a mock implementation of IGetUser for testing.
Craig Stuntz
A: 

Using your Membership Provider you can validate a user using Membership.ValidateUser. Then you can set the authentication cookie using FormsAuthentication.SetAuthCookie. As long as you have a cookie container this should allow you to log in a user.

Rune Grimstad
+2  A: 

I've found it most convenient to create a disposable class that handles setting and resetting Thread.CurrentPrincipal.

    public class TemporaryPrincipal : IDisposable {
        private readonly IPrincipal _cache;

        public TemporaryPrincipal(IPrincipal tempPrincipal) {
            _cache = Thread.CurrentPrincipal;
            Thread.CurrentPrincipal = tempPrincipal;
        }

        public void Dispose() {
            Thread.CurrentPrincipal = _cache;
        }
    }

In the test method you just wrap your call with a using statement like this:

using (new TemporaryPrincipal(new AnonymousUserPrincipal())) {
    ClassUnderTest.MethodUnderTest();
}
+2  A: 

if(Membership.ValidateUser("user1",P@ssw0rd)) { FormsAuthentication.SetAuthCookie("user1",true); }