Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing controller Action that uses User.Identity.Name

I have an action that relies on User.Identity.Name to get the username of the current user to get a list of his orders:

public ActionResult XLineas()
    {
        ViewData["Filtre"] = _options.Filtre;
        ViewData["NomesPendents"] = _options.NomesPendents;
        return View(_repository.ObteLiniesPedido(User.Identity.Name,_options.Filtre,_options.NomesPendents));
    }

Now I'm trying to write unit tests for this, but I get stuck on how to provide a Mock for User.Identity.Name. If I run my test as I have it (without mock for User...), I get a Null.. exception.

Which is the correct approach for this? I'm thinking that my Action code is not good for unit testing.

like image 811
Carles Company Avatar asked Sep 07 '09 14:09

Carles Company


2 Answers

You can use this code

public SomeController CreateControllerForUser(string userName)  {     var mock = new Mock<ControllerContext>();     mock.SetupGet(p => p.HttpContext.User.Identity.Name).Returns(userName);     mock.SetupGet(p => p.HttpContext.Request.IsAuthenticated).Returns(true);      var controller = new SomeController();     controller.ControllerContext = mock.Object;      return controller; } 

It uses Moq mocking framework, but sure you can use anything you like.

like image 74
Sly Avatar answered Nov 09 '22 17:11

Sly


A better way of doing this would be to pass a string argument userName (or an IPrincipal argument user, if you need more information than just the name) to the ActionMethod, which you "inject" in a normal request using an ActionFilterAttribute. When you test it, you just supply your own mock object, as the action filter's code will not run (in most cases - there are ways to, if you specifically want to...)

Kazi Manzur Rashid describes this in detail under point 7 in an excellent blog post.

like image 27
Tomas Aschan Avatar answered Nov 09 '22 18:11

Tomas Aschan