I have implemented Integration Tests for my .Net Core API using xUnit, shared Class Fixtures, and dependency injection so I can use WebApplicationFactory.
public class DatabaseFixture : WebApplicationFactory<Startup> {
public DatabaseFixture(WebApplicationFactory<Startup>) {
//Initialize Stuff
}
}
public class SaveTests : IClassFixture<DatabaseFixture> {
private DatabaseFixture databaseFixture;
public SaveTests(DatabaseFixture databaseFixture)
{
this.applicationFixture = applicationFixture;
}
//Tests.....
}
public class SaveTests2 : IClassFixture<DatabaseFixture> {
private DatabaseFixture databaseFixture;
public SaveTests2(DatabaseFixture databaseFixture)
{
this.applicationFixture = applicationFixture;
}
//Tests.....
}
This has worked well, but, the Test Data is initialized for each test file.
I am looking to update my tests to use a Collection Fixture instead of a Class Fixture however I have been unable to implement a Collection Fixture while injecting WebApplicationFactory.
[CollectionDefinition("SaveTestCollection")]
public class SaveTestCollectionFixture : ICollectionFixture<DatabaseFixture>
{
}
public class DatabaseFixture : WebApplicationFactory<Startup> {
public DatabaseFixture(WebApplicationFactory<Startup>) {
//Initialize Stuff
}
}
[Collection("SaveTestCollection")]
public class SaveTests
{
DatabaseFixture fixture;
public SaveTests(DatabaseFixture fixture)
{
this.fixture = fixture;
}
}
The error I get is:
System.AggregateException : One or more errors occurred. (Collection fixture type 'DatabaseFixture' had one or more unresolved constructor arguments: WebApplicationFactory) (The following constructor parameters did not have matching fixture data: DatabaseFixture fixture)
---- Collection fixture type 'DatabaseFixture' had one or more unresolved constructor arguments: WebApplicationFactory`1 factory
---- The following constructor parameters did not have matching fixture data: DatabaseFixture fixture
I understand that the Dependency Injection is failing, but I am not sure how to fix it.
So my question is, am I able to include the WebApplicationFactory via Dependency Injection, or do I need to change how I am using WebApplicationFactory to work with Collection Fixtures?
Any help is greatly appreciated
Ended up implementing the following solution, which is documented on the XUnit Github page:
Main Collection to provide the WebApplicationFactory
[CollectionDefinition("Tests")]
public class FixtureCollection : ICollectionFixture<WebApplicationFactory<Startup>>
{
}
public class SaveTestDatabaseFixture : WebApplicationFactory<Startup>{
public static SaveTestDatabaseFixture Instance;
public TestData first_test_data { get; set; }
public SaveTestDatabaseFixture(WebApplicationFactory<Startup> factory)
{
if (Instance != null)
{
return;
}
var context = factory.GetContext();
......
first_test_data = new TestData();
context.TestData.Add(first_test_data);
context.SaveChanges();
Instance = this;
}
}
All tests use the static instance of the Database Fixture.
[Collection("Tests")]
public class TestDataTests : IClassFixture<SaveTestDatabaseFixture> {
private readonly SaveTestDatabaseFixture databaseFixture;
public TestDataTests (SaveTestDatabaseFixture _)
{
this.databaseFixture = SaveTestDatabaseFixture.Instance;
}
[Fact]
public async Task Test1()
{
var x = databaseFixture.TestData.Id;
//Run Test
}
}
[Collection("Tests")]
public class TestData2Tests : IClassFixture<SaveTestDatabaseFixture> {
private readonly SaveTestDatabaseFixture databaseFixture;
public TestData2Tests (SaveTestDatabaseFixture _)
{
this.databaseFixture = SaveTestDatabaseFixture.Instance;
}
[Fact]
public async Task Test2()
{
var x = databaseFixture.TestData2.Id;
//Run Test
}
}
As I have quite a few separate test files, this change reduced the amount of data being saved to the Test Database by 90% (2000 rows down to 200 rows). It also reduced the execution time of the test suite (including Database setup time) from from 53 seconds to 20 seconds.