单元测试 AuthorizationHandler

Posted

技术标签:

【中文标题】单元测试 AuthorizationHandler【英文标题】:Unit test AuthorizationHandler 【发布时间】:2018-12-18 17:38:39 【问题描述】:

我在 .NET Core 2.1 中使用了基于资源的授权模式,如 here 所述。我唯一的问题是我不知道如何干净地测试我的AuthorizationHandler

这里有人做过类似的事情吗?

AuthorizationHandler 示例(来自上述链接):

public class DocumentAuthorizationHandler : 
    AuthorizationHandler<SameAuthorRequirement, Document>

    protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
                                                   SameAuthorRequirement requirement,
                                                   Document resource)
    
        if (context.User.Identity?.Name == resource.Author)
        
            context.Succeed(requirement);
        

        return Task.CompletedTask;
    


public class SameAuthorRequirement : IAuthorizationRequirement  

【问题讨论】:

【参考方案1】:

所有必需的依赖项都可用于独立的单元测试。

可通过Task HandleAsync(AuthorizationHandlerContext context) 访问所需的测试方法HandleRequirementAsync

/// <summary>
/// Makes a decision if authorization is allowed.
/// </summary>
/// <param name="context">The authorization context.</param>
public virtual async Task HandleAsync(AuthorizationHandlerContext context)

    if (context.Resource is TResource)
    
        foreach (var req in context.Requirements.OfType<TRequirement>())
        
            await HandleRequirementAsync(context, req, (TResource)context.Resource);
        
    

并且该成员仅依赖于AuthorizationHandlerContext,其构造函数如下

public AuthorizationHandlerContext(
    IEnumerable<IAuthorizationRequirement> requirements,
    ClaimsPrincipal user,
    object resource) 

    //... omitted for brevity

Source

验证DocumentAuthorizationHandler 的预期行为的简单隔离单元测试。

public async Task DocumentAuthorizationHandler_Should_Succeed() 
    //Arrange    
    var requirements = new []  new SameAuthorRequirement();
    var author = "author";
    var user = new ClaimsPrincipal(
                new ClaimsIdentity(
                    new Claim[] 
                        new Claim(ClaimsIdentity.DefaultNameClaimType, author),
                    ,
                    "Basic")
                );
    var resource = new Document 
        Author = author
    ;
    var context = new AuthorizationHandlerContext(requirements, user, resource);
    var subject = new DocumentAuthorizationHandler();

    //Act
    await subject.HandleAsync(context);

    //Assert
    context.HasSucceeded.Should().BeTrue(); //FluentAssertions

【讨论】:

以上是关于单元测试 AuthorizationHandler的主要内容,如果未能解决你的问题,请参考以下文章

来自 AuthorizationHandler (ASP.NET Core) 的自定义重定向

自定义AuthorizationHandler HandleRequirementAsync未调用

AuthorizationHandler 和数据库依赖注入

有没有办法在 .Net 5 中的 AuthorizationHandler 中重定向?

Django单元测试测试视图问题,怎么解决

.NET 单元测试的艺术&单元测试之道C#版