我试图在Moq中设置对模拟对象的方法的期望。同时,使用Ninject,每当调用者想要相应的接口时,我都会尝试让内核返回我的设置模拟。为了更清楚,这里有一些伪代码
Class Car {
Void buildChassis() {
Engine = ObjectBuilder.get<Iengine>()
Engine.performCheckup()
}
}
在测试buildChassis时,我想插入一个模拟引擎。
Mock<Iengine>().setup().etc.etc.etc
然而,Moq对Ninject并不好看:我无法做到这一点。我想知道是否有任何强大的软件包可以整合DI和模拟。我无法使ninject.moq包工作,也不会成熟。
答案 0 :(得分:3)
我使用和喜欢Moq,但使用与Ninject不同的IoC容器。我从来没有觉得需要集成mocking / isolation和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框架,则只需更改一个或两个顶级类。
答案 1 :(得分:0)
+ 1'd其他答案 - 一个让一切正常工作的神奇工具很少是正确的答案。重要的是要考虑在测试中必须进行大量设置的事实是否试图告诉您有关代码结构的信息。此外,您不希望将测试绑定到太多垃圾 - 理想情况下,一次只能绑定到一个单元,并仔细考虑您添加的任何依赖项。如果您的测试的上下文设置(安排)过去并且做了大量不属于您的测试的通用材料,那将成为吸引相互依赖和巧合的磁铁,将其滚成泥球。最终,只要您想调整生产代码的某个方面,就必须在测试代码上进行重新排列。