我们正在运行一个项目,在开发开始很久之后我们开始采用测试驱动设计。
我们有单元测试和集成测试。集成测试在真实数据库上运行,在运行测试之前以已知状态初始化。
在我们编写测试时,我们开始注意到,甚至对于那些可以在“标准方式”下进行测试的类,我们也是如此。使用模拟对象,它实际上变得更快,更清晰(阅读:更短和更容易理解代码),只使用直接与数据库交谈的真实对象/服务,而不是使用复杂的模拟对象设置混乱测试类。
这种方法有什么问题吗?
答案 0 :(得分:2)
如果您使用的是真实对象/服务,那么您不知道测试失败的原因。例如。您在服务实现中更改了某些内容,或者重命名了数据库字段,或者您的网络已关闭 - 您有50个失败的“单元”测试。此外,在这种情况下,您无法进行测试驱动开发,因为在您编写测试之前,应该执行您正在测试的类所需的依赖项。您能预见到服务的消费者需要哪种API吗?这将导致可用的API和代码不太常用(参数,方法等)。
如果您的测试需要付出很多努力来安排模拟,那么:
答案 1 :(得分:1)
根本没有错。相反,根据我的经验,我会说支持单元测试是错误的。你的团队对测试感觉更快,更清洁"和我多年前以及从那时起的情况一样。
我甚至建议您完全放弃单元测试,并继续投资集成测试。我说这是一个用一个非常复杂的模拟API开发一个测试库的人,他多年来一直对孤立的单元测试提出疑问,然后最终得出结论集成测试(在编写了两种类型的测试之后)是所以更好。
但是,有一个更正:单元测试"隔离&用模拟对象" 不"标准方式"。您可能知道,Kent Beck是"father" of TDD和JUnit的发明者。但是猜猜看,肯特在他的TDD单元测试中根本没有使用模拟。严格来说,"单位"由发明TDD的人编写的测试更接近集成测试,因为他们不会将测试单元与其依赖关系隔离开来。 (这是关于单元测试的常见误解。有关准确的定义,请参阅Martin Fowler撰写的this article。)