模拟ScheduledExecutorService真的会让我的类更容易测试,但是根据mockito recommendations这似乎是一个坏主意,因为模拟类的逻辑可能会以某种方式改变一种不正确的方式,但单元测试仍然会报告成功。
似乎为它编写包装将是" clean"但是我觉得这只会导致界面的完全重复,这会让我的代码变得不那么简单。我希望遵循this answer的实际建议,但我不确定ScheduledExecutorService的合同是否始终保持不变。
我可以假设ScheduledExecutorService(或更一般地说,JRE库中的任何其他类)的现有方法的合同永远不会改变吗?如果没有,如果我在集成测试中测试它的正确使用是否足够,同时仍然在单元测试中直接嘲笑它?
答案 0 :(得分:2)
我说"不要模仿你不拥有的模型!" 是正确推理中的错误结论。
如果您的 API发生变化,或者您的代码使用依赖的部分,则只需要更改单元测试。
例:您将依赖关系的接口作为输入参数,但您测试的代码在该接口中仅使用一种方法。如果你没有模仿这个界面(这是你不拥有的类型),你必须创建自己的虚拟实现,实现所有的接口方法,即使是那些你没有&# 39; t use。
如果更改该依赖项的版本,则此接口可能具有其他方法和/或某些方法已被删除。您必须在整个程序中更改您的此接口的所有实现。如果您嘲笑此界面,则无需更改测试,但仍然可以确保您的代码行为在所需的重构后没有发生变化。
此外,您的Unittest应该只会失败,因为您的代码的行为发生了变化,而不是因为依赖行为的变化。 依赖行为的变化应该使用单独的Unittest来设置依赖行为(如果它对您的应用程序至关重要)和/或集成测试。
答案 1 :(得分:2)
这更像是一条准则,而不是一条规则;做最有可能导致干净,可靠和非脆弱测试的事情。与您引用的文件一样:
这不是一个强硬路线,但越过这条线可能会产生影响! (很可能会)
这里有一个重要的事情是“不要模拟你不拥有的类型”通常是指具体或内部类型,因为那些更有可能更改版本之间的行为,或获取或丢失Mockito动态覆盖可能无法接受的final
或static
等修饰符。毕竟,如果你手动子类化第三方类,Java会抛出编译器错误; Mockito的语法会将这一点隐藏起来直到测试运行时。
列出我想到的因素:
final
方法或方法可见性的常见更改。虽然我强烈反对“不要嘲笑你不拥有的类型”作为一般的启发式或代码味道,但我同意你的意见,这种类型值得嘲笑,除非你要写并测试一个完整的实现,用于其他测试 - 这是你在这里的最佳途径。