Skip to content

This library provides utility classes for writing integration tests in dotnet using XUnit and WebApplicationFactory.

License

Notifications You must be signed in to change notification settings

ArwynFr/dotnet-integration-testing

Repository files navigation

ArwynFr.IntegrationTesting

This library provides utility classes for writing integration tests in dotnet using XUnit and WebApplicationFactory.

Nuget.org Nuget.org GitHub License

Installation

dotnet new classlib -n MyTestProject
dotnet add package ArwynFr.IntegrationTesting
dotnet add package Microsoft.NET.Test.Sdk
dotnet add package xunit.runner.visualstudio

Usage

Read advanced usage documentation for further details.

By default, the lib redirects the tested application logs to XUnit output, so you get them in the test output in case of failure. It also overwrites the application configuration with values from user secrets and environement variables.

public class MyTest(ITestOutputHelper output) : IntegrationTestBase<Program>(output)
{
    // Override a service with fake implementation in the tested app
    protected override void ConfigureAppServices(IServiceCollection services)
        => services.AddSingleton<IMyService, FakeService>();

    [Fact]
    public async Task OnTest()
    {
        // Call system under test
        var response = await Client.GetFromJsonAsync<OrderDto>($"/order");

        response.Should().HaveValue();
    }
}

EntityFrameworkCore integration

If your application uses EFcore, add the DbContext as a generic parameter and provide a configuration method. You can override the DbContext lifetime strategy according to your needs:

public class TestBaseDb(ITestOutputHelper output) : IntegrationTestBase<Program, MyDbContext>(output)
{
    // Create and drop a database for every test execution
    protected override IDatabaseTestStrategy<Context> DatabaseTestStrategy
        => IDatabaseTestStrategy<MyDbContext>.DatabasePerTest;

    // Configure EFcore with a random database name par test
    protected override void ConfigureDbContext(DbContextOptionsBuilder builder)
        => builder.UseSqlite($"Data Source={Guid.NewGuid()}.sqlite");

    [Fact]
    public async Task OnTest()
    {
        // Access the injected dbcontext
        var value = await Database.Values
            .Where(val => val.Id == 1)
            .Select(val => val.Result)
            .FirstOrDefaultAsync();

        // Call system under test
        var result = await Client.GetFromJsonAsync<int>("/api/value/1");

        result.Should().Be(value + 1);
    }
}

OpenTelemetry integration

You can access OTEL activities produced by your application in your tests. This requires you to list which activities to monitor:

public class OpenTelemetryTests(ITestOutputHelper output) : IntegrationTestBase<Program>(output)
{
    // Tell the library which OTEL sources you want to monitor
    // Traces from other sources will be ignored
    protected override string[] OpenTelemetrySourceNames => ["SourceA", "SourceB"];

    [Fact]
    public async Task Otel()
    {
        // Call system under test
        await Client.GetAsync("/otel");

        // Assert on the collection of all activities collected
        Activities.Any(activity => activity.DisplayName == "Hello").Should().BeTrue();
    }
}

Contributing

This project welcomes contributions:

Request for support:
We do not provide commercial support for this product.

Disclose vulnerability:
Read our security policy
Create a new security advisory on GitHub

Report malfunctions:
Create a new issue on GitHub

Suggest a feature:
Create a new issue on GitHub

Offer some code:
Read our definition of done
Fork the repository
Submit a pull-request

Moderate contributions:
Read our governance policy
This project is not currently appointing new moderators.