Using a test collection with test fixture in 5 steps

Sometimes you need some generic setup code for your tests. As you might know the constructor is called for every test Fact in your test class. For setup code that only needs to run once you can define a Test Fixture class. In the steps below is outlined how this can be accomplished in C#.

Define a collection definition by using the CollectionDefinition attribute

namespace XUnitTestProject
{
    using Xunit;

    [CollectionDefinition("MyTestCollection")]
    public class MyTestCollectionDefinition : ICollectionFixture<MyTestFixture>
    {
    }
}

Create the MyTextFixture class

public class EWCTestFixture
{
    public MyDbContext Context;

    public MyTestFixture()
    {
        MySqlConnection Connection = new MySqlConnection(connectionString);

        Context = new MyDbContext(userService, new DbContextOptionsBuilder<MyDbContext>()
            .UseMySql(Connection, ServerVersion.AutoDetect(Connection.ConnectionString)).Options);
        Context.Database.EnsureCreated();
        Connection.Open();
    }
}

Create a test collection for this fixture by using the Collection attribute (be sure you use the same name as used by the CollectionDefinition). The test framework takes care of injecting the MyTestFixture into the constructor.

[Collection("MyTestCollection")]
public class MyDbContextShould : IDisposable
{
    private MyTestFixture Fixture;

    private IDbContextTransaction transaction { get; }

    public MyDbContextShould(MyTestFixture fixture)
    {
        this.Fixture = fixture;
        this.transaction = Fixture.Context.Database.BeginTransaction();
    }
}

Use the test fixture in your test facts where needed.

[Fact]
public void MyObjectIsStoreInheDatabase()
{
    Fixture.Context.MyObjects.Add(new MyObject());
    Fixture.Context.SaveChanges();
    Assert.Single(Fixture.Context.MyObjects);
}

Finally define a dispose object to dispose the transaction created in the constructor.

public void Dispose()
{
    this.transaction.Dispose();
}
Share

Leave a Reply

Your email address will not be published. Required fields are marked *