集成测试时如何绕过自定义属性?

How do I bypass a Custom Attribute when Integration Testing?

基本上,我想使用 net6.0 进行干净的集成测试。我想调用我的控制器的端点,它最终会进入数据库并写入一些数据。之后,我将断言插入数据的某些方面。

我可以绕过 [Authorize] 属性使用的 Bearer Token 但无法绕过名为 [HasPermission]

的自定义属性

我有这个自定义属性:

public class HasPermission : TypeFilterAttribute
{
    public HasPermission(string resource, string scope) 
        : base(typeof(HasPermissionAuthorize))
    {
        Arguments = new object[] { resource, scope };
    }
};

public class HasPermissionAuthorize : IAuthorizationFilter
{
    private readonly string _resource;
    private readonly string _scope;
    private readonly IAuthService _authService;
    
    public HasPermissionAuthorize(string resource, string scope, IAuthService authService)
    {
        _resource = resource;
        _scope = scope;
        _authService = authService;

    }
    public async void OnAuthorization(AuthorizationFilterContext context)
    {
        string token = context.HttpContext.Request.Headers["Authorization"];

        token = token.Replace("Bearer ", "");

        bool hasPermission = await _authService.HasClaimAsync(token, "permission", _resource + "." + _scope);

        if (!hasPermission)
        {
            context.Result = new UnauthorizedResult();
        }
    }

这是我的控制器:

[Authorize] //<-- I can bypass this
[Route("v1/[controller]")]
[ApiController]
public class MachinesController : ControllerBase
{
    [HasPermission("Machines", "Create")] //<-- How do I bypass this?
    [HttpPost]
    public async Task<IActionResult> Post([FromBody] AddMachineRequest request)
    {
        //some logic
    }
}

在我的集成测试中

public class ApiWebApplicationFactory : WebApplicationFactory<Startup>
{
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.ConfigureServices(services =>
        {
            //I'm bypassing the [Authorize] attribute here
            //However, I do not know how to bypass [HasPermission] attribute
            services.AddMvc(options =>
            {
                var policy = new AuthorizationPolicyBuilder()
                    .RequireAuthenticatedUser()
                    .AddAuthenticationSchemes("Test")
                    .Build();

                options.Filters.Add(new AuthorizeFilter(policy));
            });
            services.AddAuthentication(options =>
                {
                    options.DefaultAuthenticateScheme = "Test";
                    options.DefaultChallengeScheme = "Test";
                    options.DefaultScheme = "Test";
                }) //TestAuthHandler is written somewhere else
                .AddScheme<AuthenticationSchemeOptions, TestAuthHandler>("Test", options => { });
        }
    }
}

我正在使用 IClassFixture<ApiWebApplicationFactory> 测试我的代码。尽管我可以绕过 [Authorize] 属性,但我找不到绕过 [HasPermission] 属性的优雅方法。

好的。我已经在考虑 Mocking IAuthService 但正如 Guru Stron 指出的那样,我选择了这种方法。所以,这是我对解决我的问题的代码的最新更新:

public class ApiWebApplicationFactory : WebApplicationFactory<Startup>
{
    protected override void ConfigureWebHost(IWebHostBuilder builder)
    {
        builder.ConfigureServices(services =>
        {
            //Added this line
            services.AddTransient<IAuthService>(_ => _authServiceMock.Object);
            //Above somewhere I also mocked it like this: 
            //_authServiceMock.Setup(c => c.HasClaimAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>())).ReturnsAsync(true);
            
            //other stuff from my original question remains here and they are the same
        }
    }
}