我应该练习“模仿者”还是“经典”TDD?

时间:2008-10-08 20:16:04

标签: tdd mocking

我已阅读(并重读)Martin Fowler的Mocks Aren't Stubs。在其中,他定义了two different approaches to TDD: "Classical" and "Mockist"。他试图回答“So should I be a classicist or a mockist?”的问题,但他承认,他从未尝试过嘲笑TDD的“玩具以外的东西”。所以我想我会问这个问题。好的答案可能会重复福勒的论点(但希望更清楚)或添加他没有想到的论点,或者自福勒上次更新2007年1月的论文以来其他人提出的论点。

5 个答案:

答案 0 :(得分:37)

我认为你不需要选择其中一个。两者都有它们的优点和缺点,它们都是工具箱的工具。 “Mockist”tdd让你在测试的内容上更加灵活,而经典的TDD使你的测试变得不那么脆弱,因为他们倾向于更多地关注输入/输出,而不是看实际的实现。在进行模拟单元测试时,我似乎在更改实现时会有更多测试中断。

我尝试尽可能使用经典的tdd(尽管我经常使用模拟框架来快速设置存根)。有时我注意到我一次开始测试太多,或者我需要太多的对象来设置测试。那时,模仿测试通常可以帮助您设置较小的测试。

这一切都很抽象,所以我希望我有意义

答案 1 :(得分:23)

关于mockist或classic tdd的问题非常关乎你正在测试的应用程序的哪个部分。如果您有一个“标准”分层架构(例如DDD),域层通常适用于经典tdd,您可以通过设置测试对象进行单元测试,调用几个方法并检查结果和/或国家。

另一方面,当您测试应用程序服务,控制器或表示逻辑时 为了获得良好的测试,通常需要进行更多的协调工作,模拟或存根。我的经验也是这些类倾向于调用你真正想要模拟或存根的其他层(webservice,datalayer,...)。这些单元测试还需要更多的设置代码,因此您只能在必要时进行模拟。

我的建议是尽可能去经典,并在必要时嘲笑。

答案 2 :(得分:14)

你可以考虑在http://www.growing-object-oriented-software.com/查看我们的书。它包括一个扩展的工作示例。正如我们写的那样,我们发现状态与交互的区别在很大程度上是误导性的,它更多地是关于一个人对OO设计的方法。

答案 3 :(得分:5)

Sandi Metz公开了一种非常实用的方法:

对象可以通过传出或传入消息与其他对象通信。消息可以是查询(返回某些内容)或命令(执行某些操作)。

有四种组合。不应测试传出的查询消息(已作为外部类的传入查询进行测试)您可以对传出的命令消息使用mockist测试方法,对其余的使用经典测试。

enter image description here

检查链接

http://jnoconor.github.io/blog/2013/10/07/the-magic-tricks-of-testing-by-sandi-metz/

https://speakerdeck.com/skmetz/magic-tricks-of-testing-ancientcityruby

Youtube

答案 4 :(得分:2)

我在TDD方面仍然相对较新 - 但我教授/介绍差异的方式是在测试类之间的集成方面考虑它,以便您不依赖于实时数据。例如,如果我有一个非常独立的类 - 不依赖于我为项目构建的其他类,并且它不会出现在实时数据/ dev环境中进行输入(如DB或API)然后我只会在NUnit或JUnit之类的东西中使用经典单元测试 - 但是当我开始测试构建类之间的交互时 - 那时它可以真正方便地模拟其他自定义类和/或外部交互 - 这样你就可以了可以挑出并测试当前类的代码,而不是试图追查你正在调用的其他类中的潜在错误。