7

My application is an ASP.NET Core 1.0 Web API.

How do I test a controller which is decorated with the Authorize attribute?

For example, with this controller and test method:

[TestMethod]
public void GetSomeDataTest()
{
   var controller = new MyController();
   Assert.AreEqual(controller.GetSomeData(), "Test");
}

[Authorize]
public ActionResult GetSomeData()
{
   return this.Content("Test");
}

This is just an example code to make it possible for you guys to answer. I am actually invoking the Controller via a TestServer object.

This has already been asked but the accepted answer doesn't work anymore. Any suggestions how I could "fake" the users' authenticity?

Pang
  • 9,564
  • 146
  • 81
  • 122
Moritz Schmidt
  • 2,635
  • 3
  • 27
  • 51

2 Answers2

5

You could set a claim principle to the current thread

[TestInitialize]
public void Initialize()
{
    var claims = new List<Claim>() 
    { 
        new Claim(ClaimTypes.Name, "UserName"),
        new Claim(ClaimTypes.Role, "Admin")
    };
    var identity = new ClaimsIdentity(claims, "TestAuth");
    var claimsPrincipal = new ClaimsPrincipal(identity);
    Thread.CurrentPrincipal = claimsPrincipal;
}

For .NET Core, you could set the user to the controller context

private MyController _ctrl;

[TestInitialize]
public void Initialize()
{
    var user = new ClaimsPrincipal(new ClaimsIdentity(new Claim[]
    {
         new Claim(ClaimTypes.Name, "UserName"),
         new Claim(ClaimTypes.Role, "Admin")
    }));

    _ctrl = new MyController();
    _ctrl.ControllerContext = new ControllerContext()
    {
        HttpContext = new DefaultHttpContext() { User = user }
    };
}

[TestMethod]
public void GetSomeDataTest()
{
    Assert.AreEqual(_ctrl.GetSomeData(), "Test");
}
Pang
  • 9,564
  • 146
  • 81
  • 122
Marcus Höglund
  • 16,172
  • 11
  • 47
  • 69
-2

Well, you are not actually invoking the controller. Rather, you are running a mock test and thus nothing is happening in the conventional way like the ASP.NET engine handling your request -- request passing through HTTP pipeline (thus authorization module).

So while testing, you should only concentrate on the internal logic of the controller action method instead of that Authorize attribute because, in your unit test method, no authentication / authorization will take place. You will setup mock and call the controller action method like any other method.

Pang
  • 9,564
  • 146
  • 81
  • 122
Rahul
  • 76,197
  • 13
  • 71
  • 125
  • Hello Rahul thank you for your answer. But would it be possible to test a controller decorated with the [Authorize] attribute? And if so how is it possible? – Moritz Schmidt Apr 03 '17 at 12:58
  • Iam actually invoking the controller via TestServer but I just wanted to keep things simple, thats why I postet this piece of code – Moritz Schmidt Apr 03 '17 at 12:59
  • Moritz Schmidt, how are you getting around Authorize with TestServer? – Brian Jun 20 '17 at 01:22
  • @Brian sorry, I didnt notice your comment until now. I skipped the testing of the controller classes, since it would be way to much effort. – Moritz Schmidt Oct 15 '17 at 14:56