Getting started
editInstall the package
Add the Meziantou.Framework.HttpClientMock package to a test project:
dotnet package add Meziantou.Framework.HttpClientMockThe 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.MapGetdoes in a minimal API. The handler returns the response: here an object thatResults.Okserializes 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
HttpClientthat sends its requests to the mock. Its base address ishttp://localhost/, so relative URLs work; absolute URLs, with any host, reach the mock too. - A request that matches no endpoint gets a
404 Not Foundresponse.
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
HttpClientreturned by CreateHttpClient. - Pass it an
HttpMessageHandlerfrom CreateHttpMessageHandler, for code that builds its ownHttpClientfrom a handler, or to put the mock at the end of a chain ofDelegatingHandler. - Register the mock in the service collection when the code uses
IHttpClientFactoryor 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.