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 clas
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)
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.
To list out the factors I think of:
final
methods or method visibility.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.
I'd say the "Don't mock type you don't own!" is the false conclusion out of the right reasoning.
Unittests should only need to be changes if your API changes or the part of an API of a dependency your code uses.
example:You us an interface of a dependency as an input parameter, but your tested code uses only one method in that interface. If you don't mock this interface (which is a type you don't own) you have to create your own dummy implementation implementing all of the interfaces methods, even those you don't use.
If you change the version of that dependency this interface might have additional method and/or some methods have been removed. You have to change all of your the implementations of this interface throughout your program. If you mocked this interface you don't need to change your tests and they still give you confidence that your codes behavior did not change after the required refactoring.
Furthermore your Unittest should only fail because the behavior of your code changed, not because of a change in the dependencies behavior. Changes in a dependencies behavior should be pinned with separate Unittest you setup for the dependencies behavior (if it is crucial for your application) and/or integration tests.