对ASP.NET Core MVC API控制器上的AuthorizeAttribute进行单元测试 [英] Unit testing an AuthorizeAttribute on an ASP.NET Core MVC API controller

查看:578
本文介绍了对ASP.NET Core MVC API控制器上的AuthorizeAttribute进行单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个ASP.NET Core MVC API,其中的控制器需要进行单元测试。

I have a ASP.NET Core MVC API with controllers that need to be unit tested.

控制器:

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<IActionResult> GetAsync()
        {
            var foos = await FooRepository.GetAsync();
            return Json(foos);
        }
    }
}

我很重要能够对 AuthorizeAttribute 的有效性进行单元测试。我们的代码库中存在属性缺失和范围不正确的问题。 这个答案正是我想要的,但是没有 ActionInvoker Microsoft.AspNetCore.Mvc.Controller 中的方法意味着我无法以这种方式进行操作。

It is essential that I am able to unit test the effectiveness of the AuthorizeAttribute. We have had issues in our code base with missing attributes and incorrect scopes. This answer is exactly what I am looking for, but not having a ActionInvoker method in Microsoft.AspNetCore.Mvc.Controller means I am not able to do it this way.

单元测试:

[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<UnauthorizedResult>(result);
}

如何对没有正确范围的用户进行单元测试可以访问我的控制器方法吗?

当前,我已经决定只测试 AuthorizeAttribute 的存在如下,但这确实不够好:

Currently I have settled for testing merely the presence of an AuthorizeAttribute as follows, but this is really not good enough:

    [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());
    }


推荐答案

这需要进行集成测试内存中的测试服务器,因为该属性在处理请求管道时由框架评估。

This would need integration testing with an in-memory test server because the attribute is evaluated by the framework as it processes the request pipeline.

ASP.NET Core中的集成测试


集成测试可确保将应用程序的组件组装在一起时可以正常运行。 ASP.NET Core支持使用单元测试框架和内置的测试Web主机进行集成测试,该主机可以用于处理请求而无需网络开销。

Integration testing ensures that an application's components function correctly when assembled together. ASP.NET Core supports integration testing using unit test frameworks and a built-in test web host that can be used to handle requests without network overhead.



[Fact]
public async Task GetAsync_InvalidScope_ReturnsUnauthorizedResult() {
    // Arrange
    var server = new TestServer(new WebHostBuilder().UseStartup<Startup>());
    var client = server.CreateClient();
    var url = "api/foo";
    var expected = HttpStatusCode.Unauthorized;

    // Act
    var response = await client.GetAsync(url);

    // Assert
    Assert.AreEqual(expected, response.StatusCode);
}

您还可以创建一个专门用于测试的启动,它将替换所有依赖项如果您不希望测试打到实际的生产实现中,则可以使用存根/模拟的DI来实现。

You can also create a start up specifically for the test that will replace any dependencies for DI with stubs/mocks if you do not want the test hitting actual production implementations.

这篇关于对ASP.NET Core MVC API控制器上的AuthorizeAttribute进行单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆