Asp中的集成测试.Net Core 6



我正在尝试在Asp中实现集成测试。Net Core 6。我试图使用不同的数据库进行测试,以及使用AllowAnonymousFilter覆盖端点身份验证。我在看这个教程。

目标是覆盖" connectionstring "属性。在主项目中使用integrationsettings.json中的内容。来自integrationtests的内容。json出现在api.Configuration.Providers[0]中。数据,因此读取该文件似乎可以工作。实际的应用程序。Json以相同的方式格式化,但使用真实数据。但是,测试仍然使用标准数据库运行。

AllowAnonymousFilter不起作用。因为这个端点需要授权,所以我得到一个401代码。我是新来的。net,我真的不知道如何解决这个问题…

测试:

public class UserControllerIntegrationTests
{    
[Fact]
public async Task Get_ReturnsUserFromDbAsync()
{
var api = new ApiWebApplicationFactory();
var client = api.CreateClient();
var response = await client.GetStringAsync("api/user?id=08da26ac-9de8-4cd8-8ca9-ce21f4952a6d");
var result = JsonConvert.DeserializeObject<UserDto>(response);
Assert.Equal("FirstName", result.FirstName);
}        
}

ApiWebApplicationFactory:

internal class ApiWebApplicationFactory : WebApplicationFactory<Program>
{
public IConfiguration Configuration { get;  private set; }
protected override void ConfigureWebHost(IWebHostBuilder builder)
{
builder.ConfigureAppConfiguration(config => 
{
Configuration = new ConfigurationBuilder()
.AddJsonFile("integrationsettings.json")
.Build();
config.AddConfiguration(Configuration);
});
builder.ConfigureTestServices(services =>
{
MvcServiceCollectionExtensions.AddMvc(services, options => options.Filters.Add(new AllowAnonymousFilter()));
});
}
}

integrationsettings.json:

{
"ConnectionStrings": {
"Database": "Server=testserver;Database=testserver;User=testserver;Password=testserver;"
}
}

;services.AddMvc(options => options.Filters.Clear());

在添加allow anonymous之前,您需要清除已经添加的过滤器。另一方面,如果清除过滤器,则不需要allow anonymous。

您可以像这样清除builder.ConfigureTestServices中的过滤器:

services.AddMvc(options => options.Filters.Clear());

我建议您不要使用这种方法。通过为编写测试来测试过滤器的实际工作将会更好,确保当匿名用户调用时,您的端点实际上返回401/403

我建议您设置一个可以用来成功调用API的integrationtest用户。当我们使用承载认证方案和OpenIDConnect时,我们通常设置一个简单的客户端凭据用户。希望您能找到一种方法来设置一个适合您的环境的用户。

当我们使用客户端凭据用户时,我们可以简单地创建一个我们在测试中使用的自定义DelegatingHandler。它通常看起来像这样:

public class BearerHttpMessageHandler : DelegatingHandler
{
private string _scope { get; set; }
private readonly ITokenAcquisition _tokenAcquisition;
public void SetScope(string scope) => _scope = scope;
public BearerHttpMessageHandler(ITokenAcquisition tokenAcquisition)
{
_tokenAcquisition = tokenAcquisition;
}
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
CancellationToken cancellationToken)
{
var accessToken = await _tokenAcquisition.GetAccessTokenForAppAsync(_scope,
authenticationScheme: JwtBearerDefaults.AuthenticationScheme);
request.Headers.Authorization =
new AuthenticationHeaderValue(JwtBearerDefaults.AuthenticationScheme, accessToken);
return await base.SendAsync(request, cancellationToken);
}
}

处理程序被添加到DI容器中,可以这样使用:

var handler = scope.ServiceProvider.GetService<BearerHttpMessageHandler>();
var authenticatedClient = Factory.CreateDefaultClient(handler);

你可以在这里阅读更多关于保护api的内容:https://learn.microsoft.com/en-us/azure/active-directory/develop/scenario-web-api-call-api-overview

最新更新