chunk1ty
chunk1ty

Reputation: 468

Why ninject gets different Db instances in nunit?

I write integration tests for ASP.NET MVC based application, and I try to resolve ninject registration issue.

So for my ASP.NET MVC registration I have

 kernel.Bind(typeof(ICustomDbContext), typeof(IUnitOfWork))
                .ToMethod(ctx => ctx.Kernel.Get<CustomDbContext>())
                .InRequestScope();

Just to clarify CustomDbContext implements IUnitOfWork and ICustomDbContext.
With that registration i guarantee that i have one unique instance per request for CustomDbContext. That registration works properly in scope of ASP.NET.

The problem is when i write integration tests.

[SetUp]
public void SetUp()
{
    kernel = NinjectConfig.CreateKernel();
}


[Test]
public async Task Test()
{
    // Arrange
    var claaService = kernel.Get<IService>();

}

On set up step i load my composition root (which is in ASP.NET MVC project).


The problem is when i get IService (Implementation of IService.cs is Service.cs and that service has dependencies to IUnitOfWork.cs and IGenericRepository.cs. IGenericRepository.cs has dependency to ICustomDbContext).
At the end when i access IService i should have same instance of CustomDbContext (and as I said in works in scope of MVC).
I have tried to resolve it in child scope, but the result is the same (they still have different hash code):

using (var childKernel1 = new ChildKernel(kernel))
{
    childKernel1.Rebind(typeof(ICustomDbContext), typeof(IUnitOfWork))
    .ToMethod(ctx => ctx.Kernel.Get<CustomDbContext>())
    .InThreadScope();

    var claaService = childKernel1.Get<IClassService>();

}

My questions are:

Upvotes: 2

Views: 184

Answers (1)

NightOwl888
NightOwl888

Reputation: 56869

Why this is happening ?

Ninject's scoping is limited to the lifetime of the container. You have setup the container to be created for each [Test] because you are using [SetUp].

This attribute is used inside a TestFixture to provide a common set of functions that are performed just before each test method is called.

[SetUp]
public void SetUp()
{
    kernel = NinjectConfig.CreateKernel();
}

If you want to use the same container across multiple tests in the same [TestFixture] (assuming this because you said "instance is not the same", but you didn't mention same as what), you need to use [OneTimeSetup] instead.

This attribute is to identify methods that are called once prior to executing any of the tests in a fixture.

[OneTimeSetUp]
public void OneTimeSetUp()
{
    kernel = NinjectConfig.CreateKernel();
}

This of course assumes all of your relevant integration tests are in a single class.

In short, your Ninject container is being re-initialized on every test, which means all instances it manages are also being re-initialized.

Upvotes: 1

Related Questions