Использовать HttpTest внутри интеграционного теста asp.net core / grpc - PullRequest
0 голосов
/ 15 октября 2019

У меня есть служба ядра ASP.NET / gRPC, которую я хочу проверить на интеграцию. Внутри сервисов grpc я делаю Flurl звонки на сторонние веб-интерфейсы. Я хочу издеваться над этими вызовами с помощью класса Flttl HttpTest. Я могу заставить его работать по-настоящему запутанным способом, но это должно быть проще.

В настоящее время:

            var client = _factory
                    .WithWebHostBuilder(builder =>
                    {
                        builder.ConfigureTestServices(services =>
                        {
                        });
                    })
                .CreateClient(new WebApplicationFactoryClientOptions 
                {BaseAddress = new Uri("http://localhost:5555")});

            using var channel = GrpcChannel.ForAddress("http://localhost:5555",
                new GrpcChannelOptions { HttpClient = client });

            var grpcClient = new MyGrpcService.MyClient(channel);

            var httpTest = new HttpTest();
            var content = new StringContent("some removed json", Encoding.UTF8, "application/json");
            httpTest.RespondWith(content, 200);

...
            var resp = await grpcClient.GetSomeDataAsync(someRequest);

nb Я создаю свой IFlurlClient вручную внутри службы, поскольку мы должны предоставитьдобавить динамический сертификат в зависимости от хоста.

Моя главная проблема заключается в том, что Flurl выполняет реальные HTTP-вызовы, а не использует HttpTest.

После некоторого копания это связано со статическим характером HttpTest.Current. Статический HttpTest.Current, который использует Flurl, настраивается в тесте, но не существует внутри сервера. Мне удалось взломать его работу путем передачи внешнего HttpTest.ResponseQueue одному внутри службы через переопределение DI FlurlClientFactoryBase, но это кажется далеко от идеала.

Есть ли канонический способ тестирования интеграцииобслуживание и наличие HttpTest Flurl's макет каких-либо исходящих HTTP-вызовов?

1 Ответ

0 голосов
/ 18 октября 2019

Чтобы Flurl мог сигнализировать (самому себе) эффективно подделывать все вызовы во время существования объекта HttpTest, не прибегая к статическому контексту (который может испортить параллельные тесты), ему нужен некоторый контекст для потокаэта информация из теста, через ваше SUT и в биты библиотеки Flurl. В .NET Core для этого используется механизм AsyncLocal<T>, который представляет собой логический контекст вызова, который может перетекать в асинхронные продолжения.

Однако через одну границу он не может проходитьпо умолчанию TestServer. Это сделано специально, как было объявлено здесь . Хотя я не пробовал, это объявление, похоже, подразумевает, что вы могли бы заставить это работать, если бы вы создали свой тестовый клиент следующим образом:

var server = new TestServer(webHostBuilder) 
{
    PreserveExecutionContext = true;
};
var client = server.CreateClient();
...