【问题标题】:What to do when Java Best Practices conflict with Mockito当 Java 最佳实践与 Mockito 冲突时该怎么办
【发布时间】:2010-01-12 21:30:14
【问题描述】:

我的开发团队已开始使用Mockito 并拥有已定义为“final”的类。我在 Joshua Bloch 的 Effective Java 和 SO 线程 When to use final 中读到所有类都应该使用 final 修饰符。线程中存在一些分歧,但我同意强制类组合的想法,除非继承有意义。

如果我想使用 Mockito 之类的测试框架来测试类,该框架要求类不具有“final”修饰符,我应该怎么做?我希望其他人在他们的测试中遇到过类似的问题发展。您的开发团队达成了哪些解决方案?

有两个明显的答案,例如使用 JMock 或删除我们要测试的类上的 'final' 修饰符,但我们想坚持使用一个外部测试框架(JUnit 除外),可能很难说服其他开发人员删除“final”修饰符。

谢谢。

【问题讨论】:

  • 制作所有的 final当然不是最佳实践...自从阅读Effective Java以来​​已经有一段时间了,但是链接线程的共识肯定没有' t 似乎也暗示了这一点。您应该标记类 final 以表明它们不应该扩展的某些原因 - 如果没有原因,它只会增加不必要的复杂性 - 正如您所发现的。此外,如果您意识到确实需要在某个地方扩展该类,则必须更改原始类的代码以编写新类 - 违反了开放/封闭原则。

标签: java mockito


【解决方案1】:

你最需要什么:

  1. 确保某人不会从您的类继承的能力,或者
  2. 能否确保您的代码可以使用您选择的模拟框架进行测试?

一般来说,我认为您不需要强制执行 (1)。对我来说,可测试性 (2) 更为重要。什么最适合您的情况?

【讨论】:

  • 可测试性更为重要,恕我直言,我相信它适合我们的情况。
  • 没有必要为了“可测试性”而牺牲设计。您可以两者兼得,只需使用正确的工具即可。在这种情况下,请使用可以模拟最终方法和类的 Java 模拟工具之一:JMockit(我自己的工具)或 PowerMock(支持 Mockito API,因此您不必完全重写现有测试)。跨度>
【解决方案2】:

如果您希望您的类是最终的,您可以让它们实现接口。接口是可模拟的。

【讨论】:

    【解决方案3】:

    正如其他答案中已经提到的,您可以让最终类实现 接口并在您的测试中模拟接口。

    这是使用 Mock 对象的好处之一;在这种情况下,它们会让您思考如何更好地组织代码。如果您的代码库对最终类有很多引用(因此绑定到具体实现),则它违反了“编程到接口”的 OO 原则,并且需要更好的可测试性将帮助您考虑重构以消除对具体实现的依赖。

    这篇关于模拟对象使用的论文Endo-testing: Unit Testing with Mock Objects 有一个标题为接口发现的章节 (4.4) 解释了模拟对象如何帮助发现接口。

    【讨论】:

    • 我喜欢接口发现的想法。
    • 当我编写使用 final 类的代码并且这个类没有实现单独的接口时,我没有违反“程序到接口,而不是实现”GoF原则。该原则要求每个类都实现一个单独的接口。对于那些愿意真正阅读它的人来说,GoF 书的其他部分清楚地说明了这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-24
    • 2017-11-08
    • 1970-01-01
    • 1970-01-01
    • 2013-08-10
    • 2013-06-23
    • 1970-01-01
    相关资源
    最近更新 更多