理解为什么我们使用反转控制容器进行单元测试

Joa*_*rar 3 c# dependency-injection ninject inversion-of-control

我目前正在考虑将Ninject纳入我的单元测试中.通过与早期问题相关的一些非常聪明的帖子(什么是Ninject以及何时使用它?,http://martinfowler.com/articles/injection.html); 我想我得到了一些核心概念,但是如果它的应用程序我正在努力.

大多数情况下,当IOC包含器出现时,它与将它们合并到单元测试中有关.但是,从实际的角度来看,在我的单元测试中使用像Ninject这样的框架是否有意义,如果我还没有将它合并到我的实际代码库中呢?

举例说明下面的例子(使用C#从James Bender的专业测试驱动开发中取消:使用TDD开发真实世界的应用程序)

[TestFixture]
public class PersonServiceTests
{
    [Test]
    public void ShouldBeAbleToCallPersonServiceAndGetPerson()
    {
        var expected = new Person {Id = 1, FirstName = “John”, LastName = “Doe”};
        var kernel = new StandardKernel(new CoreModule());
        var personService = kernel.Get < PersonService > ();
        var actual = personService.GetPerson(expected.Id);
        Assert.AreEqual(expected.Id, actual.Id);
        Assert.AreEqual(expected.FirstName, actual.FirstName);
        Assert.AreEqual(expected.LastName, actual.LastName);
    }
}
Run Code Online (Sandbox Code Playgroud)

如何使用Ninject编写我的测试改善我的生活(或任何继承我的代码的可怜的开发人员),而不是仅仅编写我的测试:

[TestFixture]
public class PersonServiceTests
{
    [Test]
    public void ShouldBeAbleToCallPersonServiceAndGetPerson()
    {
        var expected = new Person {Id = 1, FirstName = “John”, LastName = “Doe”};
        var personService = new PersonService();
        var actual = personService.GetPerson(expected.Id);
        Assert.AreEqual(expected.Id, actual.Id);
        Assert.AreEqual(expected.FirstName, actual.FirstName);
        Assert.AreEqual(expected.LastName, actual.LastName);
    }
}
Run Code Online (Sandbox Code Playgroud)

因为我将依赖倒置原则纳入我的代码中; 我认为IOC容器的价值是减少冗余/集中代码的一种方式,这些代码与我的类的实例化方式有关(因为尊重依赖性反转原则).但是,如果我不想在我的代码中使用IOC容器,那么将Ninject这样的东西单独用作我的单元测试框架堆栈的一部分是否可行?

Sam*_*der 5

为什么要在测试中使用DI框架?您的对象图表难以撰写吗?

我个人认为你最好只是让测试明确地创建它们的依赖关系,然后注入模拟或存根将在测试中显式并且非常明显.

它还隐藏了创建复杂依赖关系层次结构的任何问题.在测试中创建所有对象意味着您必须感受到创建这些依赖项的痛苦,并可能激励您改进设计.

我不认为使用DI框架会在这种情况下为您购买任何东西,除了模糊您的测试所具有的依赖项.

集成测试可能是一个不同的故事,但对于单元测试......

  • 对于集成测试,您可能需要使用容器,但不能用于单元测试.+1 (2认同)
  • 这似乎是一个很好的容器.我肯定应该有一天尝试一下:-) (2认同)