模拟ScheduledExecutorService与“不要模拟您不拥有的类型"哲学 [英] Mocking ScheduledExecutorService vs the "Don't mock type you don't own" philosophy

查看:80
本文介绍了模拟ScheduledExecutorService与“不要模拟您不拥有的类型"哲学的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

模拟 ScheduledExecutorService 确实使我的课程测试更加容易,但是根据 mockito建议这似乎是个坏主意,因为模拟类的逻辑可能会以不正确的方式更改,但单元测试仍会报告成功.

Mocking ScheduledExecutorService would really make testing my classes easier, but according to the mockito recommendations this seems a bad idea, as the logic of the mocked class can change in a way that it would be used in an incorrect way, but unit tests would still report success.

为它编写包装程序似乎是干净"的方式,但是我感觉这只会导致接口的完全重复,这只会使我的代码不那么直接.我想遵循此答案的实用建议,但是我不确定 ScheduledExecutorService 将始终保持不变.

It seems that writing a wrapper for it would be the "clean" way, but I have a feeling that this would merely result in the complete duplication of an interface, which would just make my code less straightforward. I'd like to follow the practical recommendations of this answer, but I am not sure that the contract of ScheduledExecutorService will always remain the same.

我可以假定

Can I assume that the contract for the existing methods of ScheduledExecutorService (or more generally, any other class in the JRE libs) will never change? If not, is it enough if I test the correct use of it in the integration tests, while still mocking it directly in the unit tests?

推荐答案

与其说它是一条规则,不如说是一条规则.做最有可能导致干净,可靠且不易碎的测试的事情.就像您在文件中引用的一样:

It's more of a guideline than a rule; do the thing that will most likely result in a clean, reliable, and non-brittle test. As in the document you quoted:

这不是一条硬线,但越过这条线可能会产生影响! (很有可能)

This is not a hard line, but crossing this line may have repercussions! (it most likely will)

这里重要的一点是,不要模拟您不拥有的类型"通常是指具体内部类型,因为这些类型更有可能在版本之间更改其行为,或获得或丢失Mockito的动态替代可能无法使用的修饰符,例如finalstatic.毕竟,如果您要手动对第三方类进行子类化,则Java会引发编译器错误. Mockito的语法会将其隐藏起来,直到测试运行时为止.

One important thing here is that "don't mock types you don't own" usually refers to concrete or internal types, because those are much more likely to change their behavior between versions, or to gain or lose modifiers like final or static that Mockito's dynamic overrides might not pick up on. After all, if you were to subclass a third-party class manually, Java would throw a compiler error; Mockito's syntax would hide that from you until test runtime.

列出我想到的因素:

  • 正如评论中的sysylias所指出的那样,您指的是一个Java接口,该接口使您免受对final方法或方法可见性的常见更改.
  • 该接口文档齐全,专为第三方扩展而设计,这又提供了Java不太可能对接口的总协定进行重大更改的另一个原因.
  • 所讨论的接口是Java中使用非常广泛的接口,总体上有很多用户,并且存在许多向后兼容的问题.与较小的库或正在积极开发的库相比,您极不可能遭受重大更改.甚至可能会说JRE处于Java语言的这种锁步中,与破坏语法更改相比,与破坏 interface 更改相比,您更担心的是. li>
  • As assylias pointed out in the comments, you're referring to a Java interface, which insulates you from common changes to final methods or method visibility.
  • The interface is well-documented and designed for third-party extension, providing yet another reason that Java would be unlikely to make breaking changes to the general contract of the interface.
  • The interface in question is a very well-used interface in Java, which overall has a lot of users, and a lot of backwards-compatibility concerns. It is very unlikely that you'd be subject to breaking changes, compared to a smaller library, or one under active development. One might even say that the JRE is in such lock step to the Java language, you have as much to worry about from breaking syntax changes than from breaking interface changes.

尽管我坚信不要嘲笑您不拥有的类型"作为一种一般的启发式或代码味道,但我在这里同意您值得嘲笑的类型,除非您要编写并测试要在其他测试中使用的完整实现,这是您前进的最佳途径.

Though I believe strongly in "don't mock types you don't own" as a general heuristic or code smell, I'd agree with you here that the type is worth mocking, and that—unless you were to write and test a full implementation to be used in other tests—it's the best path forward for you here.

这篇关于模拟ScheduledExecutorService与“不要模拟您不拥有的类型"哲学的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆