Bjo*_*pen 14 unit-testing mocking
前段时间我读过Martin Fowler撰写的Mocks Are Not Stubs文章,我必须承认,我有点害怕外部依赖关于增加的复杂性,所以我想问:
单元测试时使用的最佳方法是什么?
是不是总是使用模拟框架来自动模拟被测试方法的依赖关系,还是更喜欢使用更简单的机制,例如测试存根?
Gis*_*shu 12
正如咒语所说的那样"去做最简单的事情."
避免使用嘲笑总是因为它们使测试脆.您的测试现在对实现调用的方法有复杂的了解,如果模拟的接口或您的实现发生了变化......您的测试会中断.这很糟糕因为你会花费额外的时间让你的测试运行而不是让你的SUT运行.测试不应与实施不适当地密切相关.
所以用你最好的判断..我更喜欢嘲笑它会帮助我节省写作 - 用n >> 3方法更新假类.
更新结语/审议:(
感谢Toran Billups举例说明了一个模拟测试.见下文)
嗨道格,我认为我们已经超越了另一场圣战 - 经典TDDers vs Mockist TDDers.我想我属于前者.
由于期望,我通常更喜欢使用模拟.当您在返回值的存根上调用方法时,它通常只会返回一个值.但是当你在模拟上调用一个方法时,它不仅会返回一个值,而且还强制要求你设置该方法首先被调用.换句话说,如果设置期望然后不调用该方法,则会抛出异常.当你设定一个期望时,你基本上是在说"如果这个方法没有被调用,那就出错了." 反之亦然,如果你在模拟上调用一个方法并且没有设置期望,它将抛出一个异常,实质上是说"嘿,当你没想到它时,你正在做什么调用这个方法."
有时你不希望对你所调用的每个方法都有期望,所以一些模拟框架将允许像模拟/存根混合一样的"部分"模拟,因为只有你设置的期望被强制执行,并且所有其他方法调用都被处理更像是一个存根,因为它只返回一个值.
但是,一个有效的地方可以使用我可以想到的存根,当你将测试引入遗留代码时.有时通过子类化您正在测试的类而不是重构所有内容以使模拟变得容易甚至可能来制作存根更容易.
对此......
避免使用模拟,因为它们会使测试变得脆弱.如果模拟的接口发生变化,您的测试现在对实现调用的方法有了复杂的了解......您的测试会中断.所以用你最好的判断.. <
...我说如果我的界面发生变化,我的测试最好休息一下.因为单元测试的重点在于它们准确地测试我现在存在的代码.