title: Unit testing an AuthorizeAttribute on an ASP.NET Core MVC API controller
body: <p>I have a ASP.NET Core MVC API with controllers that need to be unit tested. </p>
  
  <p><strong>Controller:</strong></p>
  
  <pre><code>using Microsoft.AspNetCore.Authorization;
  using Microsoft.AspNetCore.Mvc;
  using System.Threading.Tasks;
  
  namespace TransitApi.Api.Controllers
  {
      [Route("api/foo")]
      public class FooController : Controller
      {
          private IFooRepository FooRepository { get; }
  
          public FooController(IFooRepository fooRepository)
          {
              FooRepository = fooRepository;
          }
  
          [HttpGet]
          [Authorize("scopes:getfoos")]
          public async Task&lt;IActionResult&gt; GetAsync()
          {
              var foos = await FooRepository.GetAsync();
              return Json(foos);
          }
      }
  }
  </code></pre>
  
  <p>It is essential that I am able to unit test the effectiveness of the <code>AuthorizeAttribute</code>. We have had issues in our code base with missing attributes and incorrect scopes. <a href="https://stackoverflow.com/a/5255237">This answer</a> is exactly what I am looking for, but not having a <code>ActionInvoker</code> method in <code>Microsoft.AspNetCore.Mvc.Controller</code> means I am not able to do it this way. </p>
  
  <p><strong>Unit Test:</strong></p>
  
  <pre><code>[Fact]
  public void GetAsync_InvalidScope_ReturnsUnauthorizedResult()
  {
      // Arrange
      var fooRepository = new StubFooRepository();
      var controller = new FooController(fooRepository)
      {
          ControllerContext = new ControllerContext
          {
              HttpContext = new FakeHttpContext()
              // User unfortunately not available in HttpContext
              //,User = new User() { Scopes = "none" }
          }
      };
  
      // Act
      var result = controller.GetAsync().Result;
  
      // Assert
      Assert.IsType&lt;UnauthorizedResult&gt;(result);
  }
  </code></pre>
  
  <p><strong>How can I unit test that users without the correct scopes are denied access to my controller method?</strong></p>
  
  <p>Currently I have settled for testing merely the presence of an <code>AuthorizeAttribute</code> as follows, but this is really not good enough:</p>
  
  <pre><code>    [Fact]
      public void GetAsync_Analysis_HasAuthorizeAttribute()
      {
          // Arrange
          var fooRepository = new StubFooRepository();
          var controller = new FooController(fooRepository)
          {
              ControllerContext = new ControllerContext
              {
                  HttpContext = new FakeHttpContext()
              }
          };
  
          // Act
          var type = controller.GetType();
          var methodInfo = type.GetMethod("GetAsync", new Type[] { });
          var attributes = methodInfo.GetCustomAttributes(typeof(AuthorizeAttribute), true);
  
          // Assert
          Assert.True(attributes.Any());
      }
  </code></pre>