XUnitAssured.Http.AspNetCore 6.15.5

There is a newer version of this package available.
See the version list below for details.
dotnet add package XUnitAssured.Http.AspNetCore --version 6.15.5
                    
NuGet\Install-Package XUnitAssured.Http.AspNetCore -Version 6.15.5
                    
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="XUnitAssured.Http.AspNetCore" Version="6.15.5" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="XUnitAssured.Http.AspNetCore" Version="6.15.5" />
                    
Directory.Packages.props
<PackageReference Include="XUnitAssured.Http.AspNetCore" />
                    
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 XUnitAssured.Http.AspNetCore --version 6.15.5
                    
#r "nuget: XUnitAssured.Http.AspNetCore, 6.15.5"
                    
#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 XUnitAssured.Http.AspNetCore@6.15.5
                    
#: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=XUnitAssured.Http.AspNetCore&version=6.15.5
                    
Install as a Cake Addin
#tool nuget:?package=XUnitAssured.Http.AspNetCore&version=6.15.5
                    
Install as a Cake Tool

XUnitAssured.Http.AspNetCore

HTTP tests against your own ASP.NET Core API. ApiFixture<TProgram> hosts the API in memory with WebApplicationFactory and hands out what those tests keep writing by hand: a shared client, a new client per identity, clients with and without cookies, the API's services and, if you ask, its logs.

Part of XUnitAssured.Net. .NET 8, 9 and 10.

Installation

dotnet add package XUnitAssured.Http.AspNetCore

Why

Every suite that tests its own API in process carries the same fixture: a WebApplicationFactory<Program> with a test environment, a client with the test user's headers, another for a user with fewer permissions, one that keeps cookies for session tests, one that does not, and a service scope for the few checks no endpoint shows. In a real consumer suite that fixture was about 120 lines, almost all of it generic.

And the usual way to use it is the slow one. An IClassFixture per test class starts the API once per class, running whatever the API does on start — database migrations included. In that suite the first test of every class took 2–6 s and the rest 0.05–0.2 s: the startups were about 70 of the suite's 118 s. One instance shared through a collection fixture brought the suite to about a minute, with no test changes.

Usage

using XUnitAssured.Http.AspNetCore;
using XUnitAssured.Http.Testing;

public sealed class MyApi : ApiFixture<Program>
{
    protected override void ConfigureApi(IWebHostBuilder api) =>
        api.UseEnvironment("Testing");

    // Who the shared client is: here, a test-only header the API reads in Testing.
    protected override void ConfigureClient(HttpClient client) =>
        client.DefaultRequestHeaders.Add("X-Test-User", "admin");
}

// One API for the whole suite.
[CollectionDefinition("API")]
public sealed class ApiCollection : ICollectionFixture<MyApi>;

[Collection("API")]
public class OrderTests(MyApi api) : HttpTestBase<MyApi>(api)
{
    [Fact]
    public async Task Admin_Lists_Orders() =>
        await Given()                       // the shared client
            .ApiResource("/orders")
            .Get()
            .ExecuteAsync()
            .AssertStatusCode(200);

    [Fact]
    public async Task Reader_Cannot_Delete() =>
        await Given(Fixture.ClientFor(("X-Test-User", "reader")))   // this test's client
            .ApiResource("/orders/1")
            .Delete()
            .ExecuteAsync()
            .AssertStatusCode(403);
}
Member What it is
CreateClient() The shared client, the one Given(fixture) uses. Created once, with ConfigureClient applied
ClientFor(("Name", "value"), ...) A new client as someone else: ConfigureClient, then these headers, each replacing one of the same name. Given(client) sends the scenario through it
ClientWithCookies() A new client with its own cookie jar, for a session that lives in a cookie
ClientWithoutCookies() A new client that never keeps cookies, to see a session from outside
Services, CreateScope() The API's services, for the checks no endpoint shows
Logs What the API logged, when CaptureLogs is true — see below
Api The WebApplicationFactory itself, for anything else
Override What it is for
ConfigureApi(IWebHostBuilder) Environment, settings and services of the API under test
ConfigureClient(HttpClient) The identity of every client the fixture creates
Authentication An HttpAuthConfig applied to every request of a Given(fixture) scenario
CaptureLogs True to record everything the API logs, at every level

The API starts with the first client or the first use of Services, and stops when xUnit disposes the fixture.

Sharing safely

One instance for the suite works when each test creates the data it reads — its own customer, its own order — and the tests of the collection run one at a time, as xUnit runs them. Two rules keep it that way:

  • Do not change the shared client. A header added in one test is there in the next. Ask for another client with ClientFor.
  • A test that changes how the API is configured needs its own instance. Derive from your fixture and give it its own collection, or create it inside the test:
public sealed class MyApiWithFakeMail : ApiFixture<Program>
{
    public FakeMail Mail { get; } = new();

    protected override void ConfigureApi(IWebHostBuilder api) =>
        api.UseEnvironment("Testing")
           .ConfigureServices(s => s.AddSingleton<IMail>(Mail));
}

[Fact]
public async Task Sends_The_Receipt()
{
    using var api = new MyApiWithFakeMail();
    // ...
}

Each instance is one more startup, so keep them to the tests that need them.

Logs

With CaptureLogs on, Logs is a LogCapture (from XUnitAssured.Core) that records every entry the API writes, at every level, without changing what the console shows. A shared host sees every test's entries, so clear it right before the action under test:

public sealed class MyApi : ApiFixture<Program>
{
    protected override bool CaptureLogs => true;
}

[Fact]
public async Task Refused_Access_Is_Logged()
{
    Fixture.Logs.Clear();

    await Given(Fixture.ClientFor(("X-Test-User", "reader")))
        .ApiResource("/orders/1")
        .Delete()
        .ExecuteAsync()
        .AssertStatusCode(403);

    Fixture.Logs.AssertLoggedOnce(predicate: l => l.Message.Contains("access denied"));
}
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 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.

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
6.31.0 0 10/16/2026
6.30.5 0 10/16/2026
6.30.1 0 10/16/2026
6.27.1 0 10/16/2026
6.27.0 0 10/16/2026
6.22.0 0 10/16/2026
6.21.3 0 10/16/2026
6.19.0 76 10/12/2026
6.18.1 72 10/12/2026
6.18.0 74 10/12/2026
6.17.0 76 10/12/2026
6.16.0 77 10/12/2026
6.15.7 80 10/12/2026
6.15.6 74 10/12/2026
6.15.5 67 10/12/2026
6.15.4 71 10/12/2026
6.15.3 79 10/12/2026
6.15.2 78 10/12/2026
6.15.1 79 10/12/2026
6.15.0 80 10/12/2026
Loading failed

Fix: the Kafka and RabbitMq timeout messages write the seconds with a dot on every machine, rounded to two places ("within 1.5s", not "1,5s" on a pt-BR machine). No code changes needed from 6.15.4. Upgrade guide: https://github.com/andrewBezerra/xunit-assured-net/blob/main/UPGRADING.md