Getting started

edit

Install the package

Add the Meziantou.Framework.HttpClientMock package to a test project:

dotnet package add Meziantou.Framework.HttpClientMock

The package references the ASP.NET Core shared framework and the test server, so the project does not need to be a web project. The examples of this documentation need using Meziantou.Framework; and using Microsoft.AspNetCore.Http;.

Mock an endpoint

Create the mock, map the endpoints the code under test calls, and create an HttpClient from the mock:

await using var mock = new HttpClientMock();
mock.MapGet("/api/users", () => Results.Ok(new { name = "John" }));
using var httpClient = mock.CreateHttpClient();
using var response = await httpClient.GetAsync(new Uri("/api/users", UriKind.Relative));
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
Assert.Equal("""{"name":"John"}""", await response.Content.ReadAsStringAsync());
  • MapGet takes the URL to match and a handler, as app.MapGet does in a minimal API. The handler returns the response: here an object that Results.Ok serializes as JSON. MapPost, MapPut, MapPatch, MapDelete, MapHead and MapOptions map the other methods. See Matching requests.
  • CreateHttpClient starts the mock on its first call and returns an HttpClient that sends its requests to the mock. Its base address is http://localhost/, so relative URLs work; absolute URLs, with any host, reach the mock too.
  • A request that matches no endpoint gets a 404 Not Found response.

Map the endpoints before you create the first client.

Give the mock to the code under test

The code under test rarely creates its own HttpClient from a mock. Depending on how it gets its client:

  • Pass it the HttpClient returned by CreateHttpClient.
  • Pass it an HttpMessageHandler from CreateHttpMessageHandler, for code that builds its own HttpClient from a handler, or to put the mock at the end of a chain of DelegatingHandler.
  • Register the mock in the service collection when the code uses IHttpClientFactory or typed clients. See Dependency injection.

Dispose the mock

HttpClientMock is IAsyncDisposable: declare it with await using, as in the example, to stop the application that runs it. Dispose the clients and handlers created from it before the mock, which using declarations do when they come after the mock's declaration.

Next steps

  • Responses: status codes, raw JSON, headers, and responses built from the request.
  • Verifying calls: check what the code under test sent.