2017-06-07 1 views
2

J'écris des tests d'intégration pour l'application basée ASP.NET MVC, et j'essaie de résoudre le problème d'enregistrement ninject.Pourquoi ninject obtient-il des instances Db différentes dans nunit?

Donc, pour mon inscription ASP.NET MVC J'ai

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

Juste pour clarifier CustomDbContext implémente IUnitOfWork et ICustomDbContext.
Avec cet enregistrement, je garantis que j'ai une instance unique par requête pour CustomDbContext. Cet enregistrement fonctionne correctement dans le cadre d'ASP.NET.

Le problème est lorsque j'écris des tests d'intégration.

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


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

} 

Sur mis en place pas je charge ma racine de composition (ce qui est dans le projet ASP.NET MVC).


Le problème est quand je reçois IService (mise en œuvre de IService.cs est Service.cs et que le service a des dépendances à IUnitOfWork.cs et IGenericRepository.cs. IGenericRepository.cs a la dépendance à l'ICustomDbContext). À la fin quand j'accède à IService je devrais avoir la même instance de CustomDbContext (et comme je l'ai dit dans les travaux dans la portée de MVC).
J'ai essayé de le résoudre dans le cadre de l'enfant, mais le résultat est le même (ils ont encore un code différent de hachage):

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

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

} 

Mes questions sont les suivantes:

  • Pourquoi cela se passe?
  • Comment puis-je le résoudre (cela fonctionne si je n'utilise pas ninject, mais je veux trouver un moyen avec Ninject, même si je dois ajouter une configuration supplémentaire dans les tests d'intégration)?

Répondre

1

Pourquoi cela se produit-il?

La portée de Ninject est limitée à la durée de vie du conteneur. Vous avez configuré le conteneur à créer pour chaque [Test] car vous utilisez [SetUp].

Cet attribut est utilisé à l'intérieur d'un TestFixture pour fournir un ensemble commun de fonctions qui sont exécutées juste avant chaque méthode de test est appelé.

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

Si vous souhaitez utiliser le même conteneur sur plusieurs essais dans le même [TestFixture] (en supposant cela parce que vous avez dit « instance est pas la même chose », mais vous ne l'avez pas mentionné même que quoi), vous besoin d'utiliser [OneTimeSetup] à la place.

Cet attribut est de trouver des méthodes qui sont appelés une fois avant l'exécution de l'un des tests dans un dispositif de fixation.

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

Ceci suppose bien entendu tous vos tests d'intégration sont pertinents dans une seule classe. En bref, votre conteneur Ninject est réinitialisé à chaque test, ce qui signifie que toutes les instances qu'il gère sont également réinitialisées.

+0

Dans chaque test, ICustomDbContext.cs et IUnitOfWork.cs doivent pointer vers la même instance de CustomDbContext.cs. et oui vous avez raison je re-initialisé sur chaque test (ce qui n'est pas correct et je vais le déplacer dans OneTimeSetUp) mais le problème est différent – chunk1ty

+0

Donc chaque test en question doit faire partie du même '[TestFixture]' dans l'ordre pour que ça marche. AFAIK, NUnit n'a pas de concept de «l'ensemble de l'application» comme le fait MVC, où vous placez normalement une [composition root] (http://blog.ploeh.dk/2011/07/28/CompositionRoot/). – NightOwl888

+0

Ils sont dans le même fichier. Pour être honnête je le configure en quelque sorte avant 2 jours, mais je rejette ces changements et je ne me souviens pas comment je l'ai fait. Je me suis souvenu que j'avais utilisé ChildKernel et l'enregistrement était similaire à celui ci-dessus. – chunk1ty