通过 WebApplicationFactory 测试内部 httpClient

xne*_*neg 5 c# unit-testing asp.net-core

好吧,我知道这有点棘手。我有一个 ASP.NET Core 站点后端 ( site),它facade通过 http与另一个系统 ( ) 通信。

但不是与HttpClient但与facade提供HttpClient底层的客户。

这些客户端的构造函数看起来像这样

public class OrdersClient : IOrdersClient
{
    private HttpClient _client;

    public OrdersClient(IEndpoint endpoint, HttpClient client) 
    { ... }
}
Run Code Online (Sandbox Code Playgroud)

注册看起来像这样

services
    .AddHttpClient("facade-client")
    .AddHttpMessageHandler<CorrelationIdDelegatingHandler>()
    .AddHttpMessageHandler<HttpErrorDelegatingHandler>()
    .AddTypedClient<IOrdersClient>((endpoint, client) => new OrdersClient(endpoint, client));
Run Code Online (Sandbox Code Playgroud)

并且配置包含(这很重要!)

app.UseCorrelationId(new CorrelationIdOptions());
Run Code Online (Sandbox Code Playgroud)

NBendpoint在这种情况下是什么并不重要。

好的。所以我想site用全新的cool来测试我的WebApplicationFactory。我创建它并site按照文档中的描述获取客户端。对于某些测试,我只是模拟客户facade喜欢

public TestOrdersClient: IOrdersClient
{
}
Run Code Online (Sandbox Code Playgroud)

并在没有facade.

进入正题。我想测试处理程序装修我HttpClient来facade。

我想如何测试处理程序:我注册了假的 PrimaryHttpMessageHandler 所以它会模仿facade我的WebApplicationFactory. 我添加了一些ImitationClient使用注册的HttpClient.

services
    .AddHttpClient("facade-client")
    .ConfigurePrimaryHttpMessageHandler(() => new HttpMessageHandlerFake())
    .AddTypedClient<ImitationClient>();
Run Code Online (Sandbox Code Playgroud)

我在这里遇到了麻烦。 在我的测试中,ImitationClient从工厂获取并尝试调用一些HttpClient内部调用的方法。

var factory = new SiteWebApplicationFactory();
var client = factory.CreateDefaultClient();

var imitationClient =factory.Server.Host.Services.GetService<ImitationClient>();
await imitationClient.GetData();
Run Code Online (Sandbox Code Playgroud)

System.NullReferenceException因为这个处理程序,我得到了:

public class CorrelationIdDelegatingHandler : DelegatingHandler
{
    private readonly ICorrelationContextAccessor _correlationAccessor;

    public CorrelationIdDelegatingHandler(ICorrelationContextAccessor correlationAccessor)
    {
        _correlationAccessor = correlationAccessor;
    }

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        request.Headers.Add(
            _correlationAccessor.CorrelationContext.Header,
            _correlationAccessor.CorrelationContext.CorrelationId);

        return base.SendAsync(request, cancellationToken);
    }
}
Run Code Online (Sandbox Code Playgroud)

关联 Id 分配给传入请求到site,然后转发到来自site到 的请求facade。但是当我只测试客户端时,facade我没有传入的请求,没有 CorrelationContext 并且失败。

最后,我的问题是如何正确地写测试内部httpClient有WebApplicationFactory。我知道我的描述相当混乱,对此我深表歉意。我准备回答有关我们项目的代码和架构的任何问题。谢谢!