我为基于ASP.NET MVC的应用程序编写集成测试,并且尝试解决ninject注册问题。

所以对于我的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>();

}


在设置步骤中,我加载了合成根目录(位于ASP.NET MVC项目中)。


问题是当我得到IService时(IService.cs的实现是Service.cs,并且该服务具有对IUnitOfWork.cs和IGenericRepository.cs的依赖。IGenericRepository.cs对ICustomDbContext的依赖)。

最后,当我访问IService时,我应该具有相同的CustomDbContext实例(正如我在MVC范围内所说的那样)。
我试图在子范围内解决它,但结果是相同的(它们仍然具有不同的哈希码):

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找到一种方法,即使我必须在集成测试中添加其他配置也可以)?

最佳答案

为什么会这样呢?


Ninject的作用域仅限于容器的使用寿命。您已设置要为每个[Test]创建的容器,因为您正在使用[SetUp]


  此属性在TestFixture内部使用,以提供一组通用功能,这些功能在调用每种测试方法之前执行。


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


如果要在同一个[TestFixture]中的多个测试中使用同一个容器(假设这是因为您说的“实例不相同”,但没有提及相同的内容),则需要使用[OneTimeSetup]代替。


  该属性用于标识在夹具中执行任何测试之前被调用一次的方法。


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


当然,这假设您所有相关的集成测试都在一个类中。

简而言之,您的Ninject容器在每次测试时都会被重新初始化,这意味着它管理的所有实例也都将被重新初始化。

关于c# - 为什么ninject在nunit中获得不同的Db实例?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44407484/

10-13 07:49