通过WebApplicationFactory

时间:2019-04-08 08:42:53

标签: c# unit-testing asp.net-core

嗯,我知道这有点棘手。我有一个ASP.NET Core网站后端(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));

配置包含(这很重要!)

app.UseCorrelationId(new CorrelationIdOptions());

在这种情况下,endpoint的用途并不重要。

好的。因此,我想用全新的酷炫site测试我的WebApplicationFactory。我创建了它,并按照文档中的说明获得了site的客户端。对于某些测试,我只是模拟facade的客户端,例如

public TestOrdersClient: IOrdersClient
{
}

并在没有facade的情况下测试我的逻辑。

关键点。我想测试将HttpClient修饰为facade的处理程序。

我要如何测试处理程序:我注册了虚假的PrimaryHttpMessageHandler,因此它将在facade中模仿WebApplicationFactory的答案。并且我添加了一些ImitationClient,它们使用了注册的HttpClient

services
    .AddHttpClient("facade-client")
    .ConfigurePrimaryHttpMessageHandler(() => new HttpMessageHandlerFake())
    .AddTypedClient<ImitationClient>();

这是我的麻烦。 在我的测试中,从工厂获得ImitationClient,并尝试调用一些在内部调用HttpClient的方法。

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

var imitationClient =factory.Server.Host.Services.GetService<ImitationClient>();
await imitationClient.GetData();

在这里我得到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);
    }
}

分配给site的传入请求的相关性ID,然后转发给从sitefacade的请求。但是,当我仅测试facade的客户端时,我没有传入请求,也没有CorrelationContext并失败。

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

0 个答案:

没有答案