.Net有很多模拟框架.没有明显的赢家在各方面都取代了其他人.领先的嘲讽框架也有很多不同风格的用法.
学习所有模拟框架以确定使用哪个框架所花费的时间是不合理的.我不相信我们已经达到了可以讨论最好的模拟框架的阶段.那么在特定情况下,我应该问什么问题,关于项目和关于我自己,以帮助决定使用的最佳模拟框架?
知道为什么选择当前使用的模拟框架以及您是否仍然对该选择感到满意也是有用的.
在比较模拟框架的样式时是否有一个有用的词汇表?
(注意:我把这个问题限制在.Net,因为Java没有属性或lambda表达式,所以我希望模拟框架可以更好地用于.Net然后Java)
截至目前的摘要:
如果你需要模拟静态方法,或者没有虚拟方法,那么唯一合理的选择是TypeMock,但是它不是免费的,并不会促使你走向一个好的设计.
如果你正在做TDD,那么Rhino Mocks是一个非常好的选择,例如你想要模拟实现接口的对象.目前它似乎是"市场领导者"
如果您使用.NET 3.5,则应考虑使用Moq(简介)Moq 可能会获得Rhino Mocks用于新项目
我从这个总结中错过了什么?
那么,如果您使用的是.NET 3.5,那么推动Rhino Mocks和Moq之间的选择又是什么呢?
也可以看看:
使用什么C#模拟框架?
Moq和Rhino.mocks有什么功能?
每个主要模拟框架的现实利弊是什么?
" 在为.NET选择依赖注入框架时,我应该考虑什么?"也可能有问题,因为它询问问题的"另一面".
那么我应该通过询问项目和我自己来帮助决定在特定情况下使用的最佳模拟框架来提出什么问题?
您应该询问有关该项目的问题是:项目是否已根据SOLID原则开发?这是一个具有松散耦合和高内聚力的项目吗?在构建项目时是否使用了良好的OO原则?是否使用了依赖注入容器?系统是否采用按合同设计方法编码(彻底利用接口)?
如果您对这些问题的回答是肯定的,那么您可以使用像RhinoMocks这样的模拟框架,这就是有些人称之为"自以为是"的框架.RhinoMocks和其他一些模拟框架对于如何设计系统以便对象进行模拟具有非常强烈的意见.像RhinoMocks这样的框架希望您的项目以某种方式设计.当您以正确的方式构建代码时,使用RhinoMocks进行模拟肯定会轻松得多(没有密封类,没有静态,大量使用接口,虚拟类方法等)
如果您对这些问题的回答是否定的,或者您正在使用具有大量高度耦合的类的遗留系统,那么您唯一的选择就是TypeMock,它可以模拟任何东西.
知道为什么选择当前正在使用的模拟框架以及如果您仍然对这个选择感到满意也是有用的.
我之所以选择RhinoMocks是因为当时(3年多以前)它显然是最成熟的模拟框架,功能最多.我一直坚持下去,因为它已经逐渐消失,使我的生活变得更加轻松(AutoMocking容器的出现是向效率迈进的巨大一步).
除了功能集和易用性之外,我喜欢RhinoMocks的是它引导我在代码中实现更好的设计.我不是一个完美的程序员,我会在设计上犯错误.但是像RhinoMocks和NHibernate这样的工具可以帮助我指导更好的设计,因为当我犯错误并创造糟糕的设计时,这些工具会变得很痛苦.例如,如果你有一个糟糕的数据库设计,NHibernate很难处理.如果您的类设计很差,没有使用接口,没有使用IoC等,RhinoMocks很难处理.
我喜欢RhinoMocks,因为它最终帮助我成为一个更好的开发人员,而不仅仅是因为我正在测试我的代码,而是因为我正在以更好的方式塑造我的代码 - 设计它.
我更喜欢Moq for .NET 3.5项目.它使用简单,根据我的经验,它有助于产生干净和清晰的单元测试.
没有技术原因可以在同一个项目中使用多个模拟框架.当然,标准化很好,但有些测试可能会更好地适应某些框架.
免责声明 - 我为Typemock工作
我不同意"Typemock不会让你做好设计".是你,开发人员驱动一个好的或坏的设计,而不是你使用的工具.获得完成工作的工具,让您高效,但良好设计的责任是您自己的.如果你认为在你的代码中包含所有类型的抽象,只是为了测试,那就去做吧,但你可能不会想出一个"好"的设计.它可能比你现在的设计更复杂.
在为.Net选择模拟框架时,我应该考虑什么
除了您正在测试的代码库的设计之外,要考虑的另一个方面是使用模拟时测试的可读性.
在这方面,我正在投票给NSubstitute--一个新的模拟框架,具有非常富有表现力的API(没有lambdas)和与Moq和Rhino Mocks类似的功能.它最近达到了1.0版.
一个用法示例(来自NSubstitute主页):
//Create: var calculator = Substitute.For(); //Set a return value: calculator.Add(1, 2).Returns(3); Assert.AreEqual(3, calculator.Add(1, 2)); //Check received calls: calculator.Received().Add(1, Arg.Any ()); calculator.DidNotReceive().Add(2, 2); //Raise events calculator.PoweringUp += Raise.Event();
这里给出了使用RhinoMocks,Moq和NSubstitute 进行测试可读性的详细比较.