C# 通过WebApplicationFactory测试内部httpClient

C# 通过WebApplicationFactory测试内部httpClient,c#,unit-testing,asp.net-core,C#,Unit Testing,Asp.net Core,我知道这个案子有点棘手。我有一个ASP.NET核心站点后端(site),它通过http与另一个系统(facade)通信 但不是使用HttpClient,而是使用facade在下面提供HttpClient的客户端 这些客户机的构造函数如下所示 public class OrdersClient : IOrdersClient { private HttpClient _client; public OrdersClient(IEndpoint endpoint, HttpClie

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

但不是使用
HttpClient
,而是使用
facade
在下面提供
HttpClient
的客户端

这些客户机的构造函数如下所示

public class OrdersClient : IOrdersClient
{
    private HttpClient _client;

    public OrdersClient(IEndpoint endpoint, HttpClient client) 
    { ... }
}
services
    .AddHttpClient("facade-client")
    .AddHttpMessageHandler<CorrelationIdDelegatingHandler>()
    .AddHttpMessageHandler<HttpErrorDelegatingHandler>()
    .AddTypedClient<IOrdersClient>((endpoint, client) => new OrdersClient(endpoint, client));
注册是这样的

public class OrdersClient : IOrdersClient
{
    private HttpClient _client;

    public OrdersClient(IEndpoint endpoint, HttpClient client) 
    { ... }
}
services
    .AddHttpClient("facade-client")
    .AddHttpMessageHandler<CorrelationIdDelegatingHandler>()
    .AddHttpMessageHandler<HttpErrorDelegatingHandler>()
    .AddTypedClient<IOrdersClient>((endpoint, client) => new OrdersClient(endpoint, client));
注意:在这种情况下,
端点的作用并不重要

嗯。所以我想用全新的酷
WebApplicationFactory
来测试我的
网站。我创建了它,并按照文档中的描述将一个客户机转到
站点
。对于一些测试,我只是将客户端模拟为
facade
like

public TestOrdersClient: IOrdersClient
{
}
在没有门面的情况下测试我的逻辑

切中要害。我想测试装饰我的
HttpClient
facade
的处理程序

如何测试处理程序:我注册了伪PrimaryHttpMessageHandler,这样它就可以模拟我的
WebApplicationFactory
facade
的答案。我添加了一些使用注册的
HttpClient
simulationclient

services
    .AddHttpClient("facade-client")
    .ConfigurePrimaryHttpMessageHandler(() => new HttpMessageHandlerFake())
    .AddTypedClient<ImitationClient>();
这里我得到了
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);
    }
}
公共类关联IDDelegatingHandler:DelegatingHandler
{
专用只读ICorrelationContextAccessor\u correlationAccessor;
公共关联IDDelegatingHandler(ICorrelationContextAccessor correlationAccessor)
{
_correlationAccessor=correlationAccessor;
}
受保护的覆盖任务SendAsync(HttpRequestMessage请求,CancellationToken CancellationToken)
{
request.Headers.Add(
_correlationAccessor.CorrelationContext.Header,
_correlationAccessor.CorrelationContext.CorrelationId);
返回base.sendaync(请求、取消令牌);
}
}
分配给
站点
的传入请求的相关Id,然后转发给从
站点
门面
的请求。但当我只测试客户端到
facade
时,我没有传入的请求,也没有CorrelationContext,所以失败了


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

首先,
TestOrdersClient
是存根,而不是模拟。通过设置实体模型和设置条件,以及如果首先调用了该方法,那么返回什么值并进行验证,以及调用的频率,可以使用moq框架创建实体模型。stuck是接口或抽象类或任何其他类的虚拟实现,这些类具有可以重写的虚拟方法?单元测试、集成测试还是验收测试?您在这方面的问题并不清楚,因为您使用模拟(单元测试中常见,测试单元时没有外部依赖项/模拟依赖项)、硬依赖项(集成测试,使用实际实现测试多个组件)和依赖项注入/IoC容器设置,这通常是在验收测试中执行的(完整应用程序启动并对其进行黑盒测试,其中只有输入和输出被控制为正确)@Tseng我可以混淆mock和stub的定义,但我希望这一点是明确的。我想测试的是,我在
Setup
中注册的所有处理程序都能正常工作。也许我写了太多关于mock的额外信息。