RSS Feed

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.

User.Identity.Name
User.Identity.IsAuthenticated

The IPrincipal is taken from the HttpContext

    public IPrincipal User
    {
      get
      {
        if (this.HttpContext != null)
          return this.HttpContext.User;
        else
          return (IPrincipal) null;
      }
    }

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

    public HttpContextBase HttpContext
    {
      get
      {
        if (this.ControllerContext != null)
          return this.ControllerContext.HttpContext;
        else
          return (HttpContextBase) null;
      }
    }

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

var user = new FakePrincipal(new FakeIdentity(userName),null);

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

var user = new FakePrincipal(new FakeIdentity(String.Empty), null);

 

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.

Code:

    public static class TestHelper
    {
        public static ControllerContext MockControllerContext(Controller controller)
        {
            var httpContext = MockRepository.GenerateMock<HttpContextBase>();
            var httpRequest = MockRepository.GenerateMock<HttpRequestBase>();
            httpContext.Stub(x => x.Request).Return(httpRequest);
            return new ControllerContext(httpContext,new RouteData(),controller);
        }

        public static ControllerContext WithAuthenticatedUser(this ControllerContext context, string userName)
        {
            var user = new FakePrincipal(new FakeIdentity(userName),null);
            context.HttpContext.Stub(x => x.User).Return(user);
            return new ControllerContext(context.HttpContext,new RouteData(),context.Controller);
        }

        public static ControllerContext WithNotAuthenticatedUser(this ControllerContext context)
        {
            var user = new FakePrincipal(new FakeIdentity(String.Empty), null);
            context.HttpContext.Stub(x => x.User).Return(user);
            return new ControllerContext(context.HttpContext, new RouteData(), context.Controller);
        }
}

Usage:

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

Hope this sample helps.


2 Comments on “Faking Controller User.Identity with Rhino Mocks and MvcContrib. Unit Tests in Asp.Net Mvc”

  1. Christian says:

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


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.