假设我们有类 Handler
和类 Validator
。 Handler
使用 Validator
来验证传入的请求。
Validator
类经过单元测试,是否返回适当的错误等。
稍后,我们要为 Handler
创建单元测试。 Validator
已经有了单元测试,那么 Handler
的测试会是什么样子呢?
我们是否会编写与 Validator
相同的测试,Handler
是否返回适当的错误(从 Validator
类检索)?这对我来说没有意义。
那么在这种情况下,Handler
类的单元测试会是什么样子?
最佳答案
Mureinik 在他的回答中提出的模拟解决方案确实是教科书解决方案。这是地球上大多数人所做的事情,也是大多数人认为正常的事情。在我看来,这也是一种严重的误导,而且我并不是唯一一个这样认为的人:
- 在视频中 Thoughtworks - TW Hangouts:TDD 已死了吗? ( youtube ) 在 21':10'' Kent Beck ( Wikipedia ) 说“我个人的做法是我几乎不 mock 任何东西。”
- 在同一视频的 23':56'' Martin Fowler ( Wikipedia ) 中添加了“我和 Kent 在一起,我几乎从不使用模拟。”
- 在他的书xUnit测试模式:重构测试代码(xunitpatterns.com)的脆弱测试部分,作者Gerard Meszaros指出“大量使用模拟对象会导致测试过度耦合”
- 在他的演讲中,TDD,哪里出了问题?( InfoQ 、 YouTube ),时间为 49 分 32 秒。Ian Cooper 说“我强烈反对模拟,因为它们过于具体。”
如果您想详细了解为什么模拟是一个坏主意,请参阅我的博客文章:michael.gr - On Mock Objects and Mocking
处理这个问题的更好方法是我称之为增量集成测试的方法。这意味着永远不要模拟任何东西,总是将实际的依赖项集成到测试中(或者是伪造的,但永远不要模拟),并简单地安排测试的执行顺序,以便首先测试最依赖的类,然后再测试类依赖于它们的内容将在之后进行测试。这样,对 Handler
的测试就可以利用 Validator
并理所当然地认为它有效,因为对 Validator
的测试已经运行了,而且已经过去了。
不幸的是,测试框架对按特定顺序执行测试提供的支持非常少(如果有的话)。我已经编写了一个工具,可以为基于 Maven 的 java 项目处理这个问题,但是您可能不使用 java 或 Maven,或者您可能不愿意使用某些人构建的一些奇怪的工具。幸运的是,有一个手动解决方法:测试框架倾向于按字母顺序执行测试,因此您仍然可以通过以字母顺序与应有的顺序一致的方式命名测试来强制执行测试的顺序。被执行。例如,您可以将测试命名为 T01_ValidatorTest
、T02_HandlerTest
等,以便 Validator
测试始终在 测试之前运行处理程序
。您可能还必须以类似的方式命名您的包和/或命名空间。
有关增量集成测试的更多信息,请参阅我的博客:michael.gr - Incremental Integration Testing
关于unit-testing - 使用已经测试过的方法的单元测试方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76247001/