我们目前正在使用Autofac作为IoC容器来遵循DI模型。
我们最近开始研究模拟框架,比如MOQ和Rhino Mocks。然而,我们似乎不能仅仅为每个接口创建模拟实现类来证明它们的用法是合理的。
为什么要这样做:
var mock = new Mock<IFoo>();
mock.Setup(foo => foo.DoSomething("ping")).Returns(true);而不是这样:
class FooMock : IFoo {
bool DoSomething(string input) {
return input == "ping";
}
}
mock = new FooMock();后者更冗长,但看起来更灵活,更适合复杂的模拟。
发布于 2011-07-05 01:10:06
您在示例中显示的内容更像是一个伪/存根,而不是一个真正的mock,而且,如果您只想要依赖对象的预封装行为,那么fake通常可能是比使用mocking框架更好的选择。
马丁·福勒写了一篇很有代表性的文章,讨论了Mocks aren't Stubs和我从其中摘录了下面这段话:
这里的关键区别是我们如何验证订单在与仓库的交互中是否做了正确的事情。对于状态验证,我们通过对仓库的状态进行断言来实现这一点。Mock使用行为验证,我们检查订单是否在仓库上进行了正确的调用。
本质上,使用mock,您通常打算检查测试中的方法如何对依赖项进行操作-您的mock具有期望,并在方法运行后验证这些期望。
当然,您仍然可以编写自己的逐个用例模拟,但使用框架将节省大量时间,提供更具可读性的测试,并节省测试中的错误。
尤其是当你的期望变得越来越复杂时,想象一下有一个测试方法,它调用一个特定依赖类的变量次数,根据输入参数的不同值而变化-这将是为自己编写一个模拟的复杂,但使用一个好的模拟框架是微不足道的。
为了用一些代码演示,想象一下这个PrintOrders方法(请原谅这个愚蠢的例子):
public void PrintForeignOrders(List<Orders> orders)
{
foreach(var order in orders)
{
if (order.IsForeign)
{
printer.PrintOrder(order.Number, order.Name);
}
}
}您可能希望至少测试以下内容:
有了一个好的模拟框架,只需敲击几下键盘,就可以针对注入的打印机对象设置这些测试。
发布于 2011-07-05 01:15:27
每次更改接口时,每个手动编码的模拟对象(实际上是一个存根)都必须进行调整,以便与新接口兼容。
因此,每次更改接口时,拥有大量手工编码的存根对象将导致大量测试代码的维护。但是,由模拟框架创建的模拟将始终与更新后的接口兼容。
发布于 2011-07-05 01:00:33
然而,我们似乎不能仅仅为我们的每个接口创建
实现类来证明它们的用法是合理的。
这正是mocking框架将您从创建stub或mock实现以测试类行为的过程中所做的事情。
你正在做的事情无论如何都没有错,如果对你的项目来说是可行的,那么一定要坚持下去--对于许多人来说,这似乎是一项非常平凡的任务,这就是使用模拟框架可以节省你大量时间的地方,也可以避免仅仅为了测试而膨胀的代码库,以及在模拟实现中出现额外错误的可能性。
https://stackoverflow.com/questions/6574199
复制相似问题