8

I am trying to figure out how I can use dependency injection with XUnit. My goal is to be able to inject my ProductRepository into my test class.

Here is the code I am trying:

public class DatabaseFixture : IDisposable
{
    private readonly TestServer _server;

    public DatabaseFixture()
    {
        _server = new TestServer(TestServer.CreateBuilder().UseStartup<Startup>());
    }

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

public class MyTests : IClassFixture<DatabaseFixture>
{
    DatabaseFixture _fixture;
    public ICustomerRepository _repository { get; set; }

    public MyTests(DatabaseFixture fixture, ICustomerRepository repository)
    {
        _fixture = fixture;
        _repository = repository;
    }
}

Here is the error: The following constructor parameters did not have matching fixture data (ICustomerRepository repository)

This leads me to believe that XUnit doens't support dependency injection, only if it is a Fixture.

Can someone give me a way of getting an instance of ProductRepository in my test class using XUnit? I believe I am correctly starting up a test server so Startup.cs runs and configures the DI.

Blake Rivell
  • 13,105
  • 31
  • 115
  • 231
  • Try this xunit di support built into xunit framework: https://www.nuget.org/packages/Xunit.Di/, so that you can inject services dependencies the same way as you do for any other applications. – cli Oct 03 '21 at 12:05

1 Answers1

7

Well, I don't think it is possible to access the container of the SUT. And to be honest I don't exactly understand why you'd want to. You will want complete control of your SUT. That means you want to provide your own dependencies to inject.

And that, you can!

_server = new TestServer(TestServer.CreateBuilder(null, app =>
{
    app.UsePrimeCheckerMiddleware();
},
services =>
{
    services.AddSingleton<IPrimeService, NegativePrimeService>();
    services.AddSingleton<IPrimeCheckerOptions, PrimeCheckerOptions>();
}));

The CreateBuilder provides overloads for this. You'll need to provide configurations and app configurations for the same reasons (reason being you want complete control over your SUT). I followed this article to make the above example if you are interested. I could also upload the sample to my GitHub if you want?

Let me know if it helped.

Update GitHub sample: https://github.com/DannyvanderKraan/ASPNETCoreAndXUnit

Community
  • 1
  • 1
Danny van der Kraan
  • 5,344
  • 6
  • 31
  • 41
  • Danny if you can upload an example to github that would be awesome. I'd have to admit that I am still a bit confused. Lets say I have a IProductRepo and a ProductRepo: Can you give me an example of the proper way to get an instance of ProductRepo using DI so I can use it in my test class? – Blake Rivell Mar 14 '16 at 13:14
  • Blake, i've updated my answer. What you would do is, instead of IPrimeService, you would write IProductRepo and instead of NegativePrimeService, you would write ProductRepo. Hope its clear now. – Danny van der Kraan Mar 14 '16 at 13:46
  • hi @DannyvanderKraan can you answer this question ? Thanks ! https://stackoverflow.com/questions/57331395/net-core-execute-all-dependency-injection-in-xunit-test-for-appservice-reposit?noredirect=1&lq=1 –  Aug 03 '19 at 03:40