单元测试自定义Web API AuthorizeAttribute

Dar*_*ght 8 c# nunit unit-testing asp.net-web-api

我正在尝试使用C#中的NUnit进行单元测试,这是一个自定义的授权属性.特别是在未被授权的情况下已经返回了特定的http状态代码和消息.

我的属性非常简单 - 看起来像这样:

public class AuthorizationAttribute : AuthorizeAttribute
{

    public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        if (IsAuthorized(actionContext))
            return;

        HandleUnauthorizedRequest(actionContext);
    }

    protected override void HandleUnauthorizedRequest(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.Forbidden, "You are not authorized to access this resource");
    }
}
Run Code Online (Sandbox Code Playgroud)

所以为了测试这个(目前在测试领域是新的),我拼凑了下面的代码.在其中,我附加了一个通用标识与用户名和一些角色数据.

public void Given_UserIsNotInAuthorizedRoles_When_Auhtorizing_ReturnsForbidden()
{

    // Arrange

    IPrincipal principal = new GenericPrincipal(new GenericIdentity("TestName"), new[] { "TestRole" });

    HttpActionContext mockActionContext = new HttpActionContext()
    {
        ControllerContext = new HttpControllerContext()
        {
            Request = new HttpRequestMessage(),
            RequestContext = new HttpRequestContext() { Principal = principal }
        },
        ActionArguments = { { "SomeArgument", "null" } }
    };

    mockActionContext.ControllerContext.Configuration = new HttpConfiguration();
    mockActionContext.ControllerContext.Configuration.Formatters.Add(new JsonMediaTypeFormatter());

    // Act
    AuthorizationAttribute authAttr = new AuthorizationAttribute();
    authAttr.OnAuthorization(mockActionContext);

    // Assert
    Assert.IsTrue(mockActionContext.Response.StatusCode == System.Net.HttpStatusCode.Forbidden);

}
Run Code Online (Sandbox Code Playgroud)

模拟控制器看起来像这样:

[Authorization(Roles = "AdminRoleOnly", Users = "A user")]
internal class MockController : ApiController { }
Run Code Online (Sandbox Code Playgroud)

当我调试时,我发现它if (IsAuthorized(actionContext))正在返回true- 我不明白.

有人能指出我为什么我的authorize属性将这个身份传递给好的方向?

对于它的价值,这段代码适用于生产.我正在回填一些测试.


有些相关,是这些

我已经通过问题和答案阅读了类似的问题ASP.NET MVC单元测试自定义AuthorizeAttribute虽然既不工作也不关联,特别是考虑到它们是用于MVC控制器而不是Api控制器.

我也读过并试图在这个问题的答案中实现代码.在测试Web.Api ActionFilter时Mocking HttpActionContext.ActionArguments


后者让我在某处,因为我的授权属性在测试中触发,我能够传递所需的上下文信息.

Nko*_*osi 3

您需要将 a 分配RoleAuthorizationAttribute. 在您的示例中,您有一个TestRole分配给委托人的任务。分配除此之外的任何其他角色。

// Act
AuthorizationAttribute authAttr = new AuthorizationAttribute() {
    Roles = "SomeOtherRole"
};
Run Code Online (Sandbox Code Playgroud)

并且测试在执行时应表现出预期的效果。

如果您查看IAuthorized的源代码,您将看到检查是否有角色分配给该属性的逻辑。如果没有可比较的,则默认为true