Dave Amour
Dave Amour

Reputation: 165

Mocking FormsAuthentication in MVC

I have the code below and want to test the scenario when FormsAuthentication returns null. How can I do this, using mocking I assume, since FormsAuthentication is a sealed class with static methods. I am using RhinoMocks.

    public PaxiumPrincipal CreatePrincipalFromCookie(string cookieValue)
    {
        var authTicket = FormsAuthentication.Decrypt(cookieValue);

        if (authTicket == null)
        {
            return null;
        };

        var userPrincipal = new PaxiumPrincipal(new GenericIdentity(authTicket.Name), null);

        return userPrincipal;
    }

Upvotes: 2

Views: 818

Answers (1)

Mattias Åslund
Mattias Åslund

Reputation: 3907

I see no evidence FormsAuthentication.Decrypt() ever returns null, other than a bug described here. Instead it throws an ArgumentException when the cookie is invalid. I think you should test that the cookie hasn't expired though..

But for the sake of argument, this is how you TDD a sealed class:

Create an interface for all methods you need

This goes into your production code:

public interface IFormsAuthentication
{
    FormsAuthenticationTicket Decrypt(string cookieValue);
}

Create a wrapper around the sealed class

This also goes into your production code:

public class MyFormsAuthentication : IFormsAuthentication
{
    public FormsAuthenticationTicket Decrypt(string cookieValue)
    {
        return FormsAuthentication.Decrypt(cookieValue);
    }
}

Change the method you want to test

It should use the IFormsAuthentication object it's provided with instead of the sealed class. In production this should be your wrapper. Obviously this is in your production code...

public class PaxiumPricipalCreator
{
    IFormsAuthentication _formsAuthentication;
    public PaxiumPricipalCreator(IFormsAuthentication formsAuthentication)
    {
        _formsAuthentication = formsAuthentication;
    }

    public PaxiumPrincipal CreatePrincipalFromCookie(string cookieValue)
    {
        var authTicket = _formsAuthentication.Decrypt(cookieValue);

        if (authTicket == null)
        {
            return null;
        };

        var userPrincipal = new PaxiumPrincipal(new GenericIdentity(authTicket.Name), null);

        return userPrincipal;
    }
}

Create a unit test with a mock authenticator (This example is in MSTest)

This is your TEST code:

[TestClass]
public class PaxiumPricipalCreatorTests
{
    [TestMethod]
    public void Returns_NULL_principal_when_IFormsAuthentication_returns_null()
    {
        var mockAuthenticator = new NullReturningFormsAuthentication();
        var principalCreator = new PaxiumPricipalCreator(mockAuthenticator);

        var actual = principalCreator.CreatePrincipalFromCookie(string.Empty);

        Assert.IsNull(actual);
    }


    public class NullReturningFormsAuthentication : IFormsAuthentication
    {
        public FormsAuthenticationTicket Decrypt(string cookieValue)
        {
            return null;
        }
    }

}

Upvotes: 1

Related Questions