ASP.NET Core - mockování HTTP závislostí v unit testech

Určitě jste se s podobnou situací setkali už nesčetněkrát - potřebujete napsat unit testy pro nějakou servisu/službu ve vaší aplikaci, ale služba obsahuje další závislosti. Například volá databázi, HTTP požadavky, pracuje se souborovým systémem a jiné.

V tomhle článku si ukážeme, jak namockovat HTTP závislosti pro lepší izolaci testované služby.

ASP.NET Core nabízí mechanismus pro práce s HttpClient - nemusíte se starat o jeho životní cyklus sami, ale vše vyřesí interní implementace IHttpClientFactory.

Registrace IHttpClientFactory

Pro registraci IHttpClientFactory, stačí zaregistrovat službu pomocí extension metody .AddHttpClient(), která zaregistruje veškeré závislosti.

services.AddHttpClient();

Poté kdekoliv v aplikaci si můžeme vyžádat IHttpClientFactory službu pomocí DI. Služba obsahuje metodu .CreateClient(), která vrací instanci HttpClient .

Mockování IHttpClientFactory

Namockujeme si službu IHttpClientFactory pomocí mockovacího frameworku NSubstitude.

 var httpClientFactoryMock = Substitute.For<IHttpClientFactory>();

Dále si naimplementujeme fake implementaci DelegatingHandler, který se stará o o zpracování requestu a vrací příslušný response.

public class FakeHttpMessageHandler : DelegatingHandler
{
   private HttpResponseMessage _fakeResponse;

   public FakeHttpMessageHandler(HttpResponseMessage responseMessage)
   {
      _fakeResponse = responseMessage;
   }

   protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   {
      return await Task.FromResult(_fakeResponse);
   }
}

Poté stačí tuhle fake implementaci podstrčit namockované IHttpClientFactory.

var fakeHttpMessageHandler = new FakeHttpMessageHandler(new HttpResponseMessage() 
{
    StatusCode = HttpStatusCode.OK,
    Content = new StringContent("OK!") // Zde si můžete serializovat objekt, který očekáváte.
});

var httpClient = new HttpClient(fakeHttpMessageHandler);

httpClientFactoryMock.CreateClient().Returns(httpClient);

A jako poslední krok zbývá vložit namockovanou instanci IHttpClientFactory do služby, kterou chceme testovat.

Written on May 21, 2020