Swevo.HttpClient.TestKit 1.0.1

Prefix Reserved
dotnet add package Swevo.HttpClient.TestKit --version 1.0.1
                    
NuGet\Install-Package Swevo.HttpClient.TestKit -Version 1.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Swevo.HttpClient.TestKit" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Swevo.HttpClient.TestKit" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="Swevo.HttpClient.TestKit" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Swevo.HttpClient.TestKit --version 1.0.1
                    
#r "nuget: Swevo.HttpClient.TestKit, 1.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Swevo.HttpClient.TestKit@1.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Swevo.HttpClient.TestKit&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=Swevo.HttpClient.TestKit&version=1.0.1
                    
Install as a Cake Tool

Swevo.HttpClient.TestKit

NuGet CI

Unit-test HttpClient calls without mocking frameworks. Fluent setup, JSON responses, request recording, and built-in verification. Zero dependencies.

var handler = new FakeHttpMessageHandler();

handler.SetupGet("https://api.example.com/users")
    .ReturnsJson(new[] { new User(1, "Alice") });

handler.SetupPost("https://api.example.com/users")
    .ReturnsJson(new User(2, "Bob"), HttpStatusCode.Created);

var client = new HttpClient(handler);

// Act
var users = await client.GetFromJsonAsync<User[]>("https://api.example.com/users");

// Verify
users.Should().ContainSingle(u => u.Name == "Alice");
handler.VerifyGetWasCalled("https://api.example.com/users");
handler.VerifyPostNeverCalled("https://api.example.com/users");

Install

dotnet add package Swevo.HttpClient.TestKit

Why not Moq?

Moq Swevo.HttpClient.TestKit
Dependencies Moq + Castle.Core Zero
Setup syntax mock.Protected().Setup<Task<HttpResponseMessage>>("SendAsync", ...) handler.SetupGet(url).ReturnsJson(...)
JSON responses Manual ReturnsJson<T>(value)
Request recording Manual handler.RecordedRequests
Verification mock.Verify(...) handler.VerifyGetWasCalled(url)

Setup methods

handler.SetupGet(url)
handler.SetupPost(url)
handler.SetupPut(url)
handler.SetupPatch(url)
handler.SetupDelete(url)
handler.Setup(HttpMethod.Options, url)   // any method

Response builders

.ReturnsJson(value)                          // 200 OK + application/json body
.ReturnsJson(value, HttpStatusCode.Created)  // 201 Created + application/json body
.ReturnsString("OK")                         // 200 OK + text/plain body
.ReturnsString("Bad Request", HttpStatusCode.BadRequest)
.ReturnsStatusCode(HttpStatusCode.NoContent) // no body
.Returns(response)                           // fixed HttpResponseMessage
.Returns(req => BuildResponse(req))          // factory — receives the original request
.Throws(new HttpRequestException("timeout")) // throws on request

Request recording

// All requests in order
handler.RecordedRequests.Should().HaveCount(3);

// Custom assertions
handler.RecordedRequests
    .Should().ContainSingle(r =>
        r.Method == HttpMethod.Post &&
        r.RequestUri!.PathAndQuery == "/users");

Verification

handler.VerifyWasCalled(HttpMethod.Get, url);        // called ≥ 1 time
handler.VerifyNeverCalled(HttpMethod.Delete, url);   // called 0 times
handler.VerifyCalledTimes(HttpMethod.Get, url, 3);   // called exactly 3 times

// Convenience
handler.VerifyGetWasCalled(url);
handler.VerifyPostWasCalled(url);
handler.VerifyPutWasCalled(url);
handler.VerifyPatchWasCalled(url);
handler.VerifyDeleteWasCalled(url);
handler.VerifyGetNeverCalled(url);
handler.VerifyPostNeverCalled(url);
handler.VerifyDeleteNeverCalled(url);

Verification methods throw InvalidOperationException on failure — compatible with any test framework.

Unmatched requests

By default, unmatched requests return 404 Not Found. Override to use strict mode:

handler.UnmatchedRequestHandler = req =>
    throw new InvalidOperationException($"Unexpected request: {req.Method} {req.RequestUri}");

URL matching

  • Exact string match, case-insensitive
  • If the same method+URL is set up twice, the last setup wins
  • Query strings are part of the URL — include them in the setup if needed

Testing a typed HttpClient

public class UserService(HttpClient client)
{
    public Task<User[]> GetUsersAsync() =>
        client.GetFromJsonAsync<User[]>("/users")!;
}

// Test
var handler = new FakeHttpMessageHandler();
handler.SetupGet("https://api.example.com/users")
    .ReturnsJson(new[] { new User(1, "Alice") });

var client = new HttpClient(handler) { BaseAddress = new Uri("https://api.example.com") };
var sut = new UserService(client);

var users = await sut.GetUsersAsync();
users.Should().HaveCount(1);

Part of the Swevo testing toolkit

Package Purpose
Swevo.HttpClient.TestKit This package
Swevo.MassTransit.TestKit Fake MassTransit request clients

License

MIT © 2026 Justin Bannister

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1 116 6/26/2026
1.0.0 94 6/26/2026

1.0.0: FakeHttpMessageHandler with SetupGet/Post/Put/Patch/Delete, ReturnsJson/String/StatusCode, RecordedRequests, VerifyWasCalled/VerifyNeverCalled/VerifyCalledTimes.