How can I unit test my ASP.NET MVC controller that uses FormsAuthentication?

12,017

I would start by writing an interface and a wrapper class that will encapsulate this logic and then use the interface in my controller:

public interface IAuth 
{
    void DoAuth(string userName, bool remember);
}

public class FormsAuthWrapper : IAuth 
{
    public void DoAuth(string userName, bool remember) 
    {
        FormsAuthentication.SetAuthCookie(userName, remember);
    }
}

public class MyController : Controller 
{
    private readonly IAuth _auth;

    public MyController(IAuth auth) 
    {
        _auth = auth;
    }

}

Now IAuth could be easily mocked in a unit test and verify that the controller calls the expected methods on it. I would NOT unit test the FormsAuthWrapper class because it just delegates the call to the FormsAuthentication which does what it is supposed to do (Microsoft guarantee :-)).

Share:
12,017

Related videos on Youtube

Deen John
Author by

Deen John

Updated on January 07, 2020

Comments

  • Deen John
    Deen John over 4 years

    I'm working with a ASP.NET MVC solution in a test driven manner and I want to login a user to my application using forms authentication. The code I would like to end up with in the controller looks something like this:

    FormsAuthentication.SetAuthCookie(userName, false);
    

    My question is how do I write a test to justify this code?

    Is there a way to check that the SetAuthCookie method was called with the correct parameters?

    Is there any way of injecting a fake/mock FormsAuthentication?

  • chadmyers
    chadmyers over 15 years
    +1 on this, don't test other people's frameworks, just YOUR usage of THEM. We do the same (similar) thing in our app (wrap FormsAuth stuff, etc)
  • Deen John
    Deen John over 15 years
    sigh Microsoft is so proud of this framework being SO testable! I was hoping there was some built in way to mock this without wrapping. Guess not :(
  • Jesse
    Jesse over 12 years
    The problem is not that the framework is not testable...the problem is that the FormsAuthentication class predates the unit-testing-design of MVC. As Darin has mentioned the best way to address this is to decouple the controller from the class with the static methods using an interface.
  • DevDave
    DevDave over 12 years
    could you give an example on how you would mock IAuth Darin?
  • Darin Dimitrov
    Darin Dimitrov over 12 years
    @Tyler, this will depend on what you are trying to unit test actually.
  • DevDave
    DevDave over 12 years
    I am just testing LogOn and its redirects, it is the standard MVC3 LogOn with minor changes, but it is the FormsAuthentication that is causing the exception in my unit tests. I don't see how the wrapper is doing anything else as it also calls FormsAuthentication
  • Darin Dimitrov
    Darin Dimitrov over 12 years
    @Tyler, you should have your AccountController take an IAuth interface at its constructor and no longer use any FormsAuthentication in it.
  • DevDave
    DevDave over 12 years
    so I could just pass in a bool 'DoNotAuth'?
  • Darin Dimitrov
    Darin Dimitrov over 12 years
    @Tyler, I don't understand what you mean. Please ask a new question, show your code so far and explain what you are trying to achieve.