2017-06-07 82 views
2

我爲基於ASP.NET MVC的應用程序編寫集成測試,並嘗試解決ninject註冊問題。爲什麼ninject在nunit中獲得不同的Db實例?

所以我的ASP.NET MVC註冊我

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

只是爲了澄清CustomDbContext實現IUnitOfWork和ICustomDbContext。
註冊我保證我有一個唯一的實例每個請求CustomDbContext。該註冊在ASP.NET的範圍內正常工作。

問題是當我編寫集成測試。

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


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

} 

在設置步驟i加載我組合物根(這是在ASP.NET MVC項目)。


問題是,當我得到IService(IService.cs的實施是Service.cs和服務有依存關係IUnitOfWork.cs和IGenericRepository.cs。IGenericRepository.cs具有依賴性ICustomDbContext)。
當我訪問IService時,我應該有相同的CustomDbContext實例(正如我在MVC作用域中所說的那樣)。
我試圖解決它在兒童範圍,但結果是一樣的(他們仍然有不同的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>(); 

} 

我的問題是:

  • 爲什麼發生這種情況?
  • 我該如何解決這個問題(如果我不使用ninject,它可以工作,但我想用Ninject找到一種方法,即使我必須在集成測試中添加其他配置)?

回答

1

爲什麼會發生這種情況?

Ninject的範圍限於容器的壽命。您已經爲每個[Test]設置了要創建的容器,因爲您使用的是[SetUp]

這一屬性用於一個的TestFixture內,以提供一組通用的,只是每個測試方法被調用之前執行功能。

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

如果你想使用在多個測試同一個容器中同[TestFixture](假設這是因爲你說的「實例是不一樣的」,但你沒有提到一樣的),你需要改用[OneTimeSetup]

該屬性用於識別在夾具中執行任何測試之前被調用一次的方法

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

當然這是假設所有的相關的集成測試是在一個類中。

簡而言之,您的Ninject容器將在每次測試中重新初始化,這意味着它所管理的所有實例也將被重新初始化。

+0

在每次測試中,ICustomDbContext.cs和IUnitOfWork.cs都應該指向CustomDbContext.cs的同一個實例。是的,你是對的我重新初始化每一個測試(這是不正確的,我會在OneTimeSetUp中移動它),但問題是不同的 – chunk1ty

+0

因此,每個測試問題需要按順序的同一個[TestFixture]的一部分爲了工作。 AFAIK,NUnit沒有像MVC那樣的「整個應用程序」的概念,這是你通常放置[合成根目錄](http://blog.ploeh.dk/2011/07/28/CompositionRoot/)的地方。 – NightOwl888

+0

它們在同一個文件中。說實話,我在2天之前配置它,但我放棄了這些變化,我不記得我是如何做到的。我記得我使用了ChildKernel,註冊類似於上面的。 – chunk1ty

相關問題