C# 通过WebApplicationFactory测试内部httpClient
我知道这个案子有点棘手。我有一个ASP.NET核心站点后端(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
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的额外信息。