Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getting an error The following constructor parameters did not have matching fixture data: PostgreSqlResource resource

I am using xunit to do integration testing, and below is my test class.

public class CodesAndGuidelinesTest : IClassFixture<SchemaCache>
{
    public readonly SchemaCache schemaCache;
    public CodesAndGuidelinesTest(PostgreSqlResource resource) 
    {
        schemaCache = new SchemaCache(resource);
    }

    [Fact]
    public async Task Create_Name_Contains_Expression()
    {
        IRequestExecutor requestExecutor = await schemaCache.CodesAndGuidelinesExecutor;
        .......
    }
}

Here is the schema cache class

public class SchemaCache : QueryTestBase
{
    Task<IRequestExecutor> _codesAndGuidelinesExecutor;
    public SchemaCache(PostgreSqlResource resource) : base(resource)
    {
        _codesAndGuidelinesExecutor = CreateDb(CodesAndGuidelinesMockFixture.codeStandardGuidelines);
    }

    public Task<IRequestExecutor> CodesAndGuidelinesExecutor
    {
        get { return _codesAndGuidelinesExecutor; }
    }
}

Here CodesAndGuidelinesMockFixture.codeStandardGuidelines is just a mock object, and When I run the test cases, I am getting the below error.

Class fixture type 'API.Tests.SchemaCache` had one or more unresolved constructor arguments: PostgreSqlResource resource, CodeStandardGuideline[] codesAndGuidelines The following constructor parameters did not have matching fixture data: PostgreSqlResource resource

I am not sure where I am doing wrong with the above code. Could anyone point me in the right direction?

Thanks!!!

Update : QueryTestBase class

public class QueryTestBase
{
    private readonly PostgreSqlResource _resource;
    public QueryTestBase(PostgreSqlResource resource)
    {
        _resource = resource;
    }

    protected async Task<Func<IResolverContext, IQueryable<T>>> BuildResolverAsync<T>(T[] arrayOfEntities) where T : class
    {
        var databaseName = Guid.NewGuid().ToString("N");
        var options = new DbContextOptionsBuilder<APIDbContext>()
            .UseNpgsql(_resource.ConnectionString)
            .Options;
        .......
        .......         
        return _ => set.AsQueryable();
    }

    protected async Task<IRequestExecutor> CreateDb<T>(T[] Entities) where T : class
    {
        Func<IResolverContext, IQueryable<T>> resolver = await BuildResolverAsync(Entities);

        return .......
    }
}
like image 630
Glory Raj Avatar asked Sep 05 '25 03:09

Glory Raj


1 Answers

Your tool (Squadron) provides an easy way to have a PostgreSqlResource.

This resource has this properties:

  • implement standard IDisposable interface (or xunit speficIAsyncLifetime interface)
  • has a parameterless contructor
// sync implementation
class PostgreSqlResource : IDisposable
{
  public PostgreSqlResource()
  {
    // init code
  }

  // props and logic 

  public Dispose()
  {
    // dispose code
  }
}

// async implementation
class PostgreSqlResource : IAsyncLifetime
{
  public PostgreSqlResource()
  {
  }

  public async Task InitializeAsync()
  {
    // init code
  }

  // props and logic 

  public async Task DisposeAsync()
  {
    // dispose code
  }
}

This object can be shared in xunit in 3 way:

  • for each test: create fixture, execute test, dispose fixture
  • for each class: create fixture, execute tests inside a class, dispose fixture
  • for a set of classes: create fixture, execute marked test classes, dispose fixture

In your case you need the 3rd way.

So Squadron provide a fixture for you, jou just need to define a TestCollection to mark your classes.

[CollectionDefinition("Squadron")]
public class DatabaseCollection : ICollectionFixture<PostgreSqlResource>
{
    // This class has no code, and is never created. Its purpose is simply
    // to be the place to apply [CollectionDefinition] and all the
    // ICollectionFixture<> interfaces.
}

and after that you can simply tag your test classes with attribute [Collection("Squadron")] that allow you in inject via constructor the shared instance.

[Collection("Squadron")]
public class DatabaseTestClass1
{
    PostgreSqlResource fixture;

    public DatabaseTestClass1(PostgreSqlResource fixture)
    {
        this.fixture = fixture;
    }
}

[Collection("Squadron")]
public class DatabaseTestClass2
{
   // ...


In case PostgreSqlResource is not enought and you need a more complex fixture is very easy; you can just create your own fixture around the other.

Of course you need to implement the same interface and delegate implementation to inner member.

class ComplexFixture: IAsyncLifetime
{
  private PostgreSqlResource _pg;

  public ComplexFixture()
  {
    _pg = new PostgreSqlResource();
  }

  // fixture methods

  public async Task InitializeAsync()
  {
    await _pg.InitializeAsync();
  }

  public async Task DisposeAsync()
  {
    await _pg.DisposeAsync();
  }
}

And refer to ComplexFixture insted of PostgreSqlResource on xunit CollectionFixtures. This approach is not suggested.


In my opinion is better a Plain fixture injected to test class, and than wrapped in a class fixture object if needed.

[Collection("Squadron")]
public class DatabaseTestClass1 : IDisposable
{
    // each test lifecycle
    private MyComplexFixture _fixture;

                              // global lifecycle
    public DatabaseTestClass1(DatabaseFixture dbFixture)
    {
        _fixture = new MyComplexFixture(dbFixture)
    }

    // tests

    public Dispose()
    {
        // this can reset db state for a new test
        _fixture.Dispose();
    }
}

public class MyComplexFixture : IDisposable
{
    public MyComplexFixture (DatabaseFixture dbFixture)
    {
      // ...
    }

    public Dispose()
    {
       // reset logic like DROP TABLE EXECUTION

       // Please note that dbFixture shoul no be disposed here!
       // xunit will dispose class after all executions.
    }
}

So applying this solution to your code can be as follows.

[CollectionDefinition("SquadronSchemaCache")]
public class DatabaseCollection : ICollectionFixture<SchemaCache>
{
}

[Collection("SquadronSchemaCache")]
public class CodesAndGuidelinesTest
{
    public readonly SchemaCache schemaCache;

    public CodesAndGuidelinesTest(SchemaCache resource) 
    {
        this.schemaCache = schemaCache;
    }

    [Fact]
    public async Task Create_Name_Contains_Expression()
    {
        IRequestExecutor requestExecutor = await schemaCache.CodesAndGuidelinesExecutor;
        .......
    }
}

public class SchemaCache : QueryTestBase
{
    Task<IRequestExecutor> _codesAndGuidelinesExecutor;
    public SchemaCache() : base(new PostgreSqlResource())
    {
        _codesAndGuidelinesExecutor = CreateDb(CodesAndGuidelinesMockFixture.codeStandardGuidelines);
    }

    public Task<IRequestExecutor> CodesAndGuidelinesExecutor
    {
        get { return _codesAndGuidelinesExecutor; }
    }
}

public class QueryTestBase : IAsyncLifetime
{
    private readonly PostgreSqlResource _resource;
    public QueryTestBase(PostgreSqlResource resource)
    {
        _resource = resource;
    }

    protected async Task<Func<IResolverContext, IQueryable<T>>> BuildResolverAsync<T>(T[] arrayOfEntities) where T : class
    {
        var databaseName = Guid.NewGuid().ToString("N");
        var options = new DbContextOptionsBuilder<APIDbContext>()
            .UseNpgsql(_resource.ConnectionString)
            .Options;
        .......
        .......         
        return _ => set.AsQueryable();
    }

    protected async Task<IRequestExecutor> CreateDb<T>(T[] Entities) where T : class
    {
        Func<IResolverContext, IQueryable<T>> resolver = await BuildResolverAsync(Entities);

        return .......
    }

    public async Task InitializeAsync()
    {
      await _resource.InitializeAsync();
    }

    public async Task DisposeAsync()
    {
        _resource.Dispose()
    }
}
like image 187
Claudio Avatar answered Sep 07 '25 21:09

Claudio