Faking Controller User.Identity with Rhino Mocks and MvcContrib. Unit Tests in Asp.Net Mvc

Some of the actions that we are writing in Asp.Net MVC contains logic which uses data from the User context eg. user authentication or user name. Controller base class contains User property which is the instance of  IPrincipal with two important properties.

The IPrincipal is taken from the HttpContext

So if your action is using the User  property directly (you can always wrap this property inside a class that implements mockable Interface ) there is a problem with unit testing. In a isolated enviroment like test case , Controller doesn’t have the HttpContext. It is an external dependency.

HttpContext is retrieved from the ControllerContext

In order to fake the User property First we need to create a fake  ControllerContext. To create it we need  HttpContext  which also needs HttpRequest.  User is created from IPrincipal and IIdentity , with those classes we can create a Stub inside the HttpContext.

Yep , It’s quite complicated. Fortunately MvcContrib Library helps a little by providing classes that are faking IIdentity and IPrincipal

If you want to create a fake user you just need to write

When creating FakeIdentity userName parametr is really important. If you want ,not authenticated user , pass Empty String as a parameter

Yey , it’s the end ! Check out this simple graph.

image

Using this information , I have implemented simple TestHelper with methods to generate Fake ControlleContext with faked User.

Usage:

Hope this sample helps.

Share on Facebook+1Share on Twitter
  • http://christianpayne.com.au Christian

    Could post a full application? This isn’t making much sense

  • Le3wood

    Fantastic post; really helpful. Thanks.

  • dave

    I am using mvc contrib and the following works very well for being able to access this.user.identity.name in the controller when being call from a unit test.

    The problem is how would i add values to the Request.Forms collection. When I use your code my Request object is null within the controller. The MVC Contrib shows code like builder.Form.Add(“testvar”, “01/01/2012″); for putting something in the forms collection.

    ProfileController.ControllerContext =
    TestHelper.MockControllerContext(ProfileController).WithAuthenticatedUser(“test”);