【问题标题】:Dependency injection and mock framework for .net.net 的依赖注入和模拟框架
【发布时间】:2010-06-30 17:18:34
【问题描述】:

我正在尝试对 Moq 中模拟对象的方法设置期望。同时,使用 Ninject,只要调用者需要相应的接口,我就会尝试让内核返回我设置的模拟。为了更清楚,这里有一些伪代码

Class Car {

    Void buildChassis() {
        Engine = ObjectBuilder.get<Iengine>()
        Engine.performCheckup()
    }
}

在测试 buildChassis 时,我想插入一个模拟引擎。

Mock<Iengine>().setup().etc.etc.etc

但是,最小起订量与 Ninject 配合得不好:我无法做到这一点。我想知道是否有任何强大的软件包可以集成 DI 和模拟。我无法让 ninject.moq 包工作,它似乎也不成熟。

【问题讨论】:

    标签: .net dependency-injection mocking moq ninject


    【解决方案1】:

    我使用和喜欢 Moq,但使用与 Ninject 不同的 IoC 容器。我从来没有觉得需要集成模拟/隔离和 IoC 容器框架。我使用构造函数注入,然后在单元测试中简单地将模拟对象传递给我的类。只有生产代码使用容器。

    恕我直言,这里真正的问题是 Car 了解 ObjectBuilder。与其将容器用作服务定位器,不如进行构造函数注入?这样一来,只有一个顶级类需要了解有关 IoC 容器的任何信息。

    class Car
    {
        public Car(IEngine engine)
        {
            // May want a null check here
            Engine = engine;
        }
    
        public IEngine Engine { get; private set; }
    }
    

    单独测试汽车很容易;创建一个模拟 IEngine 并将其传递给构造函数。

    如果以后需要创建引擎,可以传入工厂接口。

    如果您决定更改为不同的 IoC 框架,您只需更改一两个顶级类。

    【讨论】:

    • 嗯,在某些情况下,您确实需要相当于创建一个类的新实例,例如,只需将其添加到列表中。在这些情况下您将如何测试? (我有这个需求……)
    • @Andrei:使用创建 IEngine 实例的方法注入 IEngineFactory(一种方式;您也可以注入委托)。 Moq可以mock工厂,然后你设置create方法的返回值返回另一个mock。
    • 另见 tavaresstudios.com/Blog/post/Unity-20-Automatic-Factories.aspx - 不确定 Ninject 是否有此功能。
    【解决方案2】:

    +1 的其他答案 - 一个让一切正常工作的大魔法工具很少是正确的答案。重要的是要考虑您必须在测试中进行大量设置这一事实是否试图告诉您有关代码结构的一些信息。此外,您不希望将您的测试与太多的垃圾联系在一起——理想情况下一次只绑定一个单元,并仔细考虑您添加的任何依赖项。如果您的测试的上下文设置(安排)继续执行并且执行了大量并非特定于您的测试的通用内容,那么这将成为相互依赖和巧合的磁石,从而滚雪球成泥球。最终,当您想要调整生产代码的某个方面时,您必须对测试代码进行大量重新排列。

    但是有http://github.com/ninject/ninject.moq

    【讨论】:

      猜你喜欢
      • 2014-09-06
      • 2012-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-14
      • 1970-01-01
      • 2017-03-08
      • 1970-01-01
      相关资源
      最近更新 更多