SweetMock.Extensions.Http
0.9.41
dotnet add package SweetMock.Extensions.Http --version 0.9.41
NuGet\Install-Package SweetMock.Extensions.Http -Version 0.9.41
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="SweetMock.Extensions.Http" Version="0.9.41" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="SweetMock.Extensions.Http" Version="0.9.41" />
<PackageReference Include="SweetMock.Extensions.Http" />
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 SweetMock.Extensions.Http --version 0.9.41
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: SweetMock.Extensions.Http, 0.9.41"
#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 SweetMock.Extensions.Http@0.9.41
#: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=SweetMock.Extensions.Http&version=0.9.41
#tool nuget:?package=SweetMock.Extensions.Http&version=0.9.41
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
SweetMock.Extensions.Http
A comprehensive extension library for mocking HttpClient and IHttpClientFactory in .NET tests using the SweetMock framework.
Features
- Mock HttpClient: Create fully controllable HTTP client mocks for testing
- Mock IHttpClientFactory: Mock factory instances with named and default clients
- Fluent API: Chainable extension methods for building HTTP responses
- Rich Response Builders: Pre-built helpers for common HTTP status codes
- Content Helpers: Easy content creation with proper MIME types
- Header Management: Simplified header, cache control, and content header configuration
Installation
dotnet add package SweetMock.Extensions.Http
Quick Start
HttpClient Fixture
[Fixture<HttpClientFixture>]
public class ServiceTests
{
[Fact]
public async Task CallApi_Success()
{
// Arrange
var fixture = Fixture.HttpClientFixture(config =>
config.client
.Initialize(baseAddress: new Uri("http://api.local/"))
.Send(message => message
.ReplyOk()
.WithJsonContent(new { status = "success" })
)
);
var sut = fixture.CreateHttpClientFixture();
// Act
var result = await sut.CallRestEndpoint("query", CancellationToken.None);
// Assert
var call = Assert.Single(fixture.Calls.client.SendAsync());
Assert.Equal("http://api.local/test?q=query", call.request!.RequestUri!.ToString());
}
}
IHttpClientFactory Fixture
[Fixture<HttpClientFactoryFixture>]
public class FactoryServiceTests
{
[Fact]
public async Task MultipleClients_ConfiguredCorrectly()
{
// Arrange
var fixture = Fixture.HttpClientFactoryFixture(config =>
{
config.factory.NamedClient("Client1", c =>
c.Initialize(new Uri("http://api1.com/"))
.Send(m => m.ReplyOk().WithStringContent("Response 1"))
);
config.factory.NamedClient("Client2", c =>
c.Send(m => m.ReplyOk().WithStringContent("Response 2"))
);
});
// Act
var sut = fixture.CreateHttpClientFactoryFixture();
await sut.ProcessData();
// Assert
var client1Calls = fixture.Calls.factory.SendAsync("Client1");
var client2Calls = fixture.Calls.factory.SendAsync("Client2");
Assert.NotEmpty(client1Calls);
Assert.NotEmpty(client2Calls);
}
}
Basic HttpClient Mock
using System.Net.Http;
[Mock<HttpClient, MockOf_HttpClient>]
public class MyServiceTests
{
[Fact]
public async Task GetData_ReturnsExpectedContent()
{
// Arrange
var httpClient = Mock.HttpClient(config =>
config.Send(request =>
request.ReplyOk().WithStringContent("Hello World")
)
);
// Act
var response = await httpClient.GetStringAsync("/api/data");
// Assert
Assert.Equal("Hello World", response);
}
}
Advanced Request Matching
var httpClient = Mock.HttpClient(config =>
config.Send(request => request.RequestUri!.AbsolutePath switch
{
"/api/users" => request.ReplyOk().WithJsonContent(new { name = "John" }),
"/api/products" => request.ReplyOk().WithJsonContent("[{\"id\":1}]"),
_ => request.ReplyNotFound()
})
);
Mock IHttpClientFactory
[Mock<IHttpClientFactory, MockOf_IHttpClientFactory>]
[Mock<HttpClient, MockHttpClient>]
public class FactoryTests
{
[Fact]
public async Task NamedClient_WorksCorrectly()
{
// Arrange
var factory = Mock.IHttpClientFactory(config =>
{
config.NamedClient("ApiClient", client =>
client
.Initialize(new Uri("https://api.example.com/"))
.Send(request => request.ReplyOk().WithStringContent("API Response"))
);
config.DefaultClient(client =>
client.Send(request => request.ReplyNotFound())
);
});
// Act
var client = factory.CreateClient("ApiClient");
var response = await client.GetStringAsync("/endpoint");
// Assert
Assert.Equal("API Response", response);
}
}
Response Builders
Status Code Helpers
The library provides convenient extension methods for common HTTP status codes:
// Success responses
request.ReplyOk() // 200 OK
request.ReplyCreated() // 201 Created
request.ReplyNoContent() // 204 No Content
// Redirection responses
request.ReplyMovedPermanently("/new-url") // 301 Moved Permanently
request.ReplyFound("/temp-url") // 302 Found
request.ReplyNotModified() // 304 Not Modified
// Client error responses
request.ReplyBadRequest() // 400 Bad Request
request.ReplyUnauthorized("Bearer") // 401 Unauthorized
request.ReplyForbidden() // 403 Forbidden
request.ReplyNotFound() // 404 Not Found
request.ReplyMethodNotAllowed() // 405 Method Not Allowed
request.ReplyConflict() // 409 Conflict
request.ReplyUnsupportedMediaType(MimeType.Json) // 415 Unsupported Media Type
request.ReplyTooManyRequests() // 429 Too Many Requests
// Server error responses
request.ReplyInternalServerError() // 500 Internal Server Error
request.ReplyBadGateway() // 502 Bad Gateway
request.ReplyServiceUnavailable() // 503 Service Unavailable
request.ReplyGatewayTimeout() // 504 Gateway Timeout
// Custom status code
request.Reply(HttpStatusCode.ImATeapot) // Any status code
Content Helpers
String and Text Content
response.WithStringContent("Plain text")
response.WithHtmlContent("<html><body>Hello</body></html>")
response.WithJsonContent("{\"key\":\"value\"}")
// .NET 9+ only: Serialize objects directly
response.WithJsonContent(new { name = "John", age = 30 })
Binary Content
byte[] data = GetBinaryData();
response.WithByteArrayContent(data) // Automatically sets Content-Length and Content-MD5
Custom Content
response.WithContent(new StringContent("data"), MimeType.Json)
Header Management
Simple Headers
response.WithHeader("X-Custom-Header", "value")
response.WithHeader("Accept-Encoding", new[] { "gzip", "deflate" })
Response Headers
response.WithHeaders(headers =>
{
headers.ETag = new EntityTagHeaderValue("\"abc123\"");
headers.Date = DateTimeOffset.UtcNow;
})
Cache Control Headers
response.WithCacheHeaders(cache =>
{
cache.NoCache = true;
cache.NoStore = true;
cache.MaxAge = TimeSpan.FromHours(1);
})
Content Headers
response.WithContentHeaders(headers =>
{
headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "document.pdf"
};
headers.ContentType = new MediaTypeHeaderValue(MimeType.ByteStream);
})
MIME Type Constants
The MimeType class provides common MIME type constants:
MimeType.Json // application/json
MimeType.Text // application/text
MimeType.Form // application/x-www-form-urlencoded
MimeType.Html // text/html
MimeType.Css // text/css
MimeType.JavaScript // text/javascript
MimeType.ByteStream // application/octet-stream
// Image types
MimeType.Image_png // image/png
MimeType.Image_jpeg // image/jpeg
MimeType.Image_gif // image/gif
MimeType.Image_svg // image/svg+xml
MimeType.Image_webp // image/webp
MimeType.Image_avif // image/avif
MimeType.Image_apng // image/apng
Inspecting Mock Calls
Track and verify HTTP requests made during tests:
MockOf_IHttpClientFactory.Logs logs = null!;
var factory = Mock.IHttpClientFactory(config =>
config
.DefaultClient(c => c.Send(message => message.ReplyOk()))
.GetCallLogs(out logs)
);
// Use the factory...
var client = factory.CreateClient();
await client.GetAsync("/test");
// Inspect calls
foreach (var call in logs.SendAsync())
{
Console.WriteLine($"Request: {call.request.Method} {call.request.RequestUri}");
}
// Filter calls by client name
var specificClientCalls = logs.SendAsync("Client1",
args => args.request!.Method == HttpMethod.Get
);
Requirements
- .NET 8.0, 9.0, or 10.0
- SweetMock
- Microsoft.Extensions.Http
License
See the main SweetMock repository for license information.
Links
| Product | Versions 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 is compatible. 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 is compatible. 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.
-
net10.0
- Microsoft.Extensions.Http (>= 10.0.0)
- SweetMock (>= 0.9.41)
-
net8.0
- Microsoft.Extensions.Http (>= 10.0.0)
- SweetMock (>= 0.9.41)
-
net9.0
- Microsoft.Extensions.Http (>= 10.0.0)
- SweetMock (>= 0.9.41)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.