.net net的依赖注入和模拟框架

.net net的依赖注入和模拟框架,.net,dependency-injection,mocking,moq,ninject,.net,Dependency Injection,Mocking,Moq,Ninject,我试图在Moq中建立对模拟对象方法的期望。同时,使用Ninject,我尝试让内核在调用方需要相应接口时返回我的setup-mock。为了更清楚,这里有一些伪代码 Class Car { Void buildChassis() { Engine = ObjectBuilder.get<Iengine>() Engine.performCheckup() } } 等级车{ Void buildChassis(){ Engine=Obje

我试图在Moq中建立对模拟对象方法的期望。同时,使用Ninject,我尝试让内核在调用方需要相应接口时返回我的setup-mock。为了更清楚,这里有一些伪代码

Class Car {

    Void buildChassis() {
        Engine = ObjectBuilder.get<Iengine>()
        Engine.performCheckup()
    }
}
等级车{
Void buildChassis(){
Engine=ObjectBuilder.get()
引擎性能检查()
}
}
测试buildChassis时,我想插入模拟引擎

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

然而,莫克对尼尼特并不友好:我无法做到这一点。我想知道是否有任何健壮的软件包可以集成DI和mocking。我无法使ninject.moq包正常工作,它似乎也不成熟。

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

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

    public IEngine Engine { get; private set; }
}
我想这里真正的问题是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框架,你只需要换一两个顶级课程。

+1另一个答案——一个能让一切正常运转的神奇工具很少是正确的答案。重要的是要考虑你在测试中必须做大量的安装是否试图告诉你代码的结构。此外,您也不希望将测试与太多垃圾捆绑在一起——理想情况下,一次只与一个单元捆绑在一起,并仔细考虑您添加的任何依赖项。如果你的测试的上下文设置(安排)去了,并且做了大量的非特定于你的测试的通用的东西,那将成为一块磁铁,吸引相互依赖和巧合,把雪球变成一团泥。最终,当您想要调整生产代码的某个方面时,您必须对测试代码进行一系列的重新排列


但是有

嗯,在某些情况下,您确实需要创建一个类的新实例,例如,只需将其添加到列表中。在这些情况下,您将如何进行测试?(我有这个需要…@Andrei:使用创建IEEngine实例的方法注入IEEngineFactory(一种方法;您也可以注入委托)。Moq可以模拟工厂,然后设置create方法的返回值以返回另一个模拟。另请参阅-不确定Ninject是否具有此功能。