7

I have just started learning and usingASP.NET MVC 2 and also getting more involved into unit testing my code. My question is broadly how to simulate a user log in by passing in credentials within my test.

I am using MSpec and trying to get my head around fakeiteasy in order to write up my test. So far, I believe I've written one test correctly (It passes the test condition) for when an unauthenticated user tries to access a page.

Subject( typeof( HomeController ) )]
public class context_for_a_home_controller_for_not_logged_user
{
    protected static HomeController HomeController;

    Establish context = () =>
    {
        // Create controller
        HomeController = new HomeController();

        HomeController.ControllerContext = A.Fake<ControllerContext>();
    };
}

[Subject(typeof(HomeController))]
public class when_the_home_page_is_requested : context_for_a_home_controller_for_not_logged_user
{
    static ActionResult result;

    Because of = () => 
        result = HomeController.Index();

    It should_return_the_log_in_page_if_user_not_logged_in = () =>
        { result.ShouldBeAView().And().ShouldUseDefaultView(); };
}

So far so good. However, I'd like to test for the scenario for when an authenticated user hits the home controller. I'm stuck in how to simulate an authenticated user and any help or advice would be welcome.

TIA,

David

DavidS
  • 2,179
  • 4
  • 26
  • 44

2 Answers2

4

After getting in touch with Patrik Hagne, the creator of FakeItEasy, he came up with the following:

 [Subject( typeof( HomeController ) )]
public class context_for_a_home_controller_for_logged_user
{
    protected static HomeController HomeController;

    Establish context = () =>
    {
        // Create controller
        HomeController = new HomeController();

        HomeController.ControllerContext = A.Fake<ControllerContext>();
        var fakePrincipal = A.Fake<IPrincipal>();
        var fakeIdentity = new GenericIdentity( "username" );
        A.CallTo( () => fakePrincipal.Identity ).Returns( fakeIdentity );
        A.CallTo( () => HomeController.ControllerContext.HttpContext.User ).Returns( fakePrincipal );
    };
}

That did the trick! Thanks Patrik!

DavidS
  • 2,179
  • 4
  • 26
  • 44
2

Here's how you could fake the identity:

Subject( typeof( HomeController ) )]
public class context_for_a_home_controller_for_a_logged_user
{
    protected static HomeController HomeController;

    Establish context = () =>
    {
        // Create controller
        HomeController = new HomeController();

        var fakeControllerContext = A.Fake<ControllerContext>();
        var fakeHttpContext = A.Fake<HttpContextBase>();
        var fakePrincipal = A.Fake<IPrincipal>();
        var fakeIdentity = new GenericIdentity("someusername");
     
        HomeController.ControllerContext = fakeControllerContext;
        A.CallTo(() => fakeControllerContext.HttpContext).Returns(fakeHttpContext);
        A.CallTo(() => fakeHttpContext.User).Returns(fakePrincipal);        
        A.CallTo(() => fakePrincipal.Identity).Returns(fakeIdentity);
    };
}

Now when you use HomeController.User property it will point to the fake principal which was provided.

DavidS
  • 2,179
  • 4
  • 26
  • 44
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • Hi Darin, thank you for posting this answer. Unfortunately the line A.CallTo(() => HomeController.User).Returns(fakePrincipal); is causing errors because HomeController is the subject under test and is not a fake object. Would you have any further suggestions to get the code going? – DavidS Dec 03 '10 at 09:24