DEV Community

tswiftma
tswiftma

Posted on

6 2

Initialize asynchronous data in XUnit Collections for sharing data between tests

By its design XUnit doesn't like to share data between tests like NUnit. XUnit has created Collection Fixtures as a method to share data between your tests and test classes. While this approach generally works I found that almost all the test data I needed to share between tests was created asynchronously! We live in an Asynchronous world now.

If you reference the XUnit link above you'll see that they initialize their example DatabaseFixture class like so:

public class DatabaseFixture : IDisposable
{
    public DatabaseFixture()
    {
        Db = new SqlConnection("MyConnectionString");

        // ... initialize data in the test database ...
    }

    public void Dispose()
    {
        // ... clean up test data from the database ...
    }

    public SqlConnection Db { get; private set; }
}
Enter fullscreen mode Exit fullscreen mode

The problem with the above code is that I can't create test data with an async/await call. There is a fairly easy way around this problem that XUnit should really document. You can derive your DatabaseFixture class from IAsyncLifeTime to provide asynchronous lifetime functionality for your test data that can be referenced in every test. To do this you create and destroy all of your test data in the InitializeAsync() and DisposeAsync() methods like so:

public class DatabaseFixture : IAsyncLifeTime
{
    // ... create your shared vars here

    public async Task InitializeAsync()
    {
        // ... initialize data in the test database and/or use async calls here ...
    }

    public async Task DisposeAsync()
    {
        // ... clean up test data from the database with and use async calls here...
    }    
}
Enter fullscreen mode Exit fullscreen mode

Now the above code example only replaces the initial class creation from XUnit. You still need to create an XUnit CollectionDefinition and Collection with all of your tests as per the examples on the XUnit page.

Note that using the IAsyncLifetime derived test class is an excellent opportunity to create your own classes to store test data. Try creating a a new class file MyTestData to store whatever you need. Could be strings, lists, guids, etc. Then under the class section // ... create your shared vars here initialize your class object:

public List<MyTestData> _testData { get; set; }
Enter fullscreen mode Exit fullscreen mode

You now can use _testData to store any type of test data you create and share it with all your tests. Pretty darn awesome.

Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

Top comments (1)

Collapse
 
xaberue profile image
Xavier Abelaira Rueda โ€ข

Nice article, great tip! you saved my day! I was struggling with this, Xunit clearly has a not to structured and clear documentation in some scenarios.

With this particular scenario, I have come to think about going to NUnit since it more clearly covered the purpose I was looking for...

BTW small typo in the DatabaseFixture code snippet, the interface is IAsyncLifetime (with the lowercase T)

Thank you so much

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

๐Ÿ‘‹ Kindness is contagious

Discover a treasure trove of wisdom within this insightful piece, highly respected in the nurturing DEV Community enviroment. Developers, whether novice or expert, are encouraged to participate and add to our shared knowledge basin.

A simple "thank you" can illuminate someone's day. Express your appreciation in the comments section!

On DEV, sharing ideas smoothens our journey and strengthens our community ties. Learn something useful? Offering a quick thanks to the author is deeply appreciated.

Okay