Faking Azure ID identity in ASP.NET Core unit tests

When testing ASP.NET Core controllers in application that uses Azure AD we need usually current user at least for some tests. As there is no authenticated user when unit testing, we need to create one by our own. This blog post shows how to create claims identity for ASP.NET Core unit tests.

To have Azure AD user available we have to create fake claims identity and fill it with claims that test expects. Then we create the instance of constructor and initiate controller and HTTP context. The latter one contains identity.

Consider the following controller action.

public IActionResult Index()
{
    var name = User.Identity.Name;

    // Do something with name

    return View();
}

Test like this will probably fail with exception as there is no code that deals with current user identity.

[Fact]
public void SampleTest()
{
    var controller = new HomeController();

    controller.Index();
}

Let’s organize typical claims identity with some claims to controller.

[Fact]
public void SampleTest()
{
    var user = new ClaimsPrincipal(new ClaimsIdentity(new Claim[]
    {
            new Claim(ClaimTypes.NameIdentifier, "SomeValueHere"),
            new Claim(ClaimTypes.Name, "gunnar@somecompany.com")
            // other required and custom claims
    }));

    var controller = new HomeController();
    controller.ControllerContext = new ControllerContext()
    {
        HttpContext = new DefaultHttpContext { User = user }
    };

    controller.Index();
}

Now we have fake claims identity available and our controller will use this. When running this test in Visual Studio we can see that controller has current user now.

aspnet-core-unit-test-claims-identity

It is also possible to use factory classes for identity. In this case we have one class for production and this returns the current identity controller has. Another class is for testing and this class creates and returns fake identity. As I don’t see much benefit on using factories with no additional value I suggest to go with directly created fake identity. Creating the identity can be moved to some helper method in test class if it is needed in multiple tests.

Gunnar Peipman

Gunnar Peipman is ASP.NET, Azure and SharePoint fan, Estonian Microsoft user group leader, blogger, conference speaker, teacher, and tech maniac. Since 2008 he is Microsoft MVP specialized on ASP.NET.

    9 thoughts on “Faking Azure ID identity in ASP.NET Core unit tests

    • July 21, 2017 at 9:53 am
      Permalink

      Hi, Gunnar, what do you think about injecting IPrincipal in the Index action method? When running your app you can use a custom model binder to automatically get IPrincipal passed into the action method but when testing you have the convenience of passing the User using the IPrincipal interface.

    • July 21, 2017 at 10:44 am
      Permalink

      With unit tests we don’t have any binders to use as binders and other things happening in HTTP request pipeline are the matter of integration tests. By example, if you decorate controller action with Authorize attribute then from tests you can still call the action without any identity available.

    • July 21, 2017 at 8:11 pm
      Permalink

      Yes, this is also one way how to do it. But then you have additional class and additional configuration. I’m sort of lazy programmer and I prefer to keep things as small as possible as codebases tend to grow over time.

    • July 21, 2017 at 8:47 pm
      Permalink

      What is a little disturbing for me on Hanselman’s solution is the fact that the need to fake the identity is on the testing side but it floats up to web application although there are other ways how to do it without leaking this need out from testing.

    • July 24, 2017 at 12:11 pm
      Permalink

      My common approach looks like yours, although, I found Hanselman’s approach interesting.

      Thank you for sharing your thoughts.

    • August 1, 2017 at 10:27 am
      Permalink

      Ho man, you are the one. Beautifully simple. Been searching the interwebs for something like this.

    • October 24, 2017 at 10:17 am
      Permalink

      Thanks this helped me alot.

    Leave a Reply

    Your email address will not be published. Required fields are marked *