views:

327

answers:

1

Hello, 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.

+4  A: 

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.

Tomas Lycken
Great. I have to look more into ActionFilters... Thanks.
Carles
I often mock IPrincipal for my tests. It allows me to test user informations (username) but also authorization (User.Identity.IsInRole).
mberube.Net
So do I. On the other hand, mocking IPrincipal just for getting access to the current user's username - and *nothing* else - is on the edge of overkill... :)
Tomas Lycken
This is such a good suggestion I want to up-vote it again!
alastairs