---
url: https://jasperfx.github.io/alba/guide/xunit.md
description: >-
  Share one AlbaHost across xUnit tests with IAsyncLifetime class and collection
  fixtures to write fast ASP.NET Core integration tests.
---

# Integrating with xUnit

If you are writing only a few Alba specifications in your testing project and your application spins up very quickly, you can just happily write tests like this:

```cs
[Fact]
public async Task should_say_hello_world()
{
    // Alba will automatically manage the lifetime of the underlying host
    await using var host = await AlbaHost.For<global::Program>();
    
    // This runs an HTTP request and makes an assertion
    // about the expected content of the response
    await host.Scenario(_ =>
    {
        _.Get.Url("/");
        _.ContentShouldBe("Hello World!");
        _.StatusCodeShouldBeOk();
    });
}
```

snippet source | anchor

Do note that your `[Fact]` method needs to be declared as `async Task` to ensure that xUnit finishes the specification before disposing the system or
you'll get *unusual* behavior. Also note that you really need to dispose the `AlbaHost` to shut down your application and dispose any internal services that might be holding on to computer resources.

## Class Fixtures

If your application startup time becomes a performance problem, and especially in larger test suites, you probably want to share the `AlbaHost` object between tests. xUnit helpfully provides the [class fixture feature](https://xunit.net/docs/shared-context) for just this use case.

Build out your `AlbaHost` in a class like this. ASP.NET Core setup goes in the configuration action, and Alba specific setup such as
configuration overrides and extensions is chained onto the builder before it is awaited (see
[Configuring the Host Fluently](gettingstarted.md#configuring-the-host-fluently)):

```cs
public class WebAppFixture : IAsyncLifetime
{
    public IAlbaHost AlbaHost = null!;

    public async ValueTask InitializeAsync()
    {
        AlbaHost = await Alba.AlbaHost.For<WebApp.Program>(builder =>
            {
                // ASP.NET Core host setup such as service registrations
            })
            // Alba specific setup such as configuration overrides and extensions
            .WithConfiguration("Alba:Fixture", "xUnit");
    }

    public async ValueTask DisposeAsync()
    {
        await AlbaHost.DisposeAsync();
    }
}
```

snippet source | anchor

Then in your actual xUnit fixture classes, implement the `IClassFixture<T>` class like this:

```cs
public class ContractTestWithAlba : IClassFixture<WebAppFixture>
{
    public ContractTestWithAlba(WebAppFixture app)
    {
        _host = app.AlbaHost;
    }

    private readonly IAlbaHost _host;
```

snippet source | anchor

## Collection Fixtures

In the previous section, the `WebAppFixture` instance will only be shared between all the tests in the one `ContractTestWithAlba` class.
To reuse the `IAlbaHost` across multiple test fixture classes, you'll need to use xUnit.Net's [Collection Fixture](https://xunit.net/docs/shared-context) concept.

Still using `WebAppFixture`, we'll now need to have a marker collection class like this:

```cs
[CollectionDefinition("scenarios")]
public class ScenarioCollection : ICollectionFixture<WebAppFixture>
{
    
}
```

snippet source | anchor

As a convenience, I like to have a base class for all test fixture classes that will be using scenarios like this:

```cs
[Collection("scenarios")]
public abstract class ScenarioContext
{
    protected ScenarioContext(WebAppFixture fixture)
    {
        Host = fixture.AlbaHost;
    }

    public IAlbaHost Host { get; }
}
```

snippet source | anchor

And then inherit from that `ScenarioContext` base class in actual test fixture classes:

```cs
public class sample_integration_fixture : ScenarioContext
{
    public sample_integration_fixture(WebAppFixture fixture) : base(fixture)
    {
    }
    
    [Fact]
    public Task happy_path()
    {
        return Host.Scenario(_ =>
        {
            _.Get.Url("/fake/okay");
            _.StatusCodeShouldBeOk();
        });
    }
}
```

snippet source | anchor
