That’s my impression as well. Almost always when people advocate narrow tests without mocks they end up using something that’s not called a mock but ultimately isn’t distinguishable from a mock.
Which I don’t think necessarily invalidates the article (which I’ve only skimmed so far, but already strikes me as having a lot going for it), just some terminology used. It’s perfectly reasonable, regardless of terminology, to say: here are some techniques that encourage testability and high confidence in those tests. And it appears to me there’s a lot of that in the article. So with that said, I’m gonna go give it a more thorough read :)
Agreed. Perhaps what differentiate those from "normal" mocks is:
1) They only apply to "infrastructure" (so databases, external services etc). Basically the article says: "It's okay to use mocks sparingly, to avoid costly and flaky tests involving external services".
2) They are defined along with the production code, and _tested accordingly_. Which I assume means that you test the "null implementations"/"infrastructure mocks" by making sure they are always aligned with the real interactions. This avoids the danger of "normal mocks" to diverge from the real interactions.
What I would like to understand better, instead, is if there is a way to avoid all of this system to break once the infrastructure is two layers below the code you're testing. Because you can inject a null implementation into ApplicationClass, but what you have a UpperApplicationClass which depends on ApplicationClass? You either have to unravel the dependencies yourself to inject NullImplementation inside ApplicationClass inside UpperApplicationClass (which defies the point of the article, in a way), or you have to resort to a DI framework, which I personally abhor (I've still to find a single case in which it is a net benefit and not just a magic way of obfuscating the code).
> Which I assume means that you test the "null implementations"/"infrastructure mocks" by making sure they are always aligned with the real interactions. This avoids the danger of "normal mocks" to diverge from the real interactions.
When using a typed language (TS, Java, etc) this is also the case for mocks, isn't it? I don't see a reason why the implementation of the `createNull()` factory should be less prone to go out of sync with the implementation than mocks (as long as the type signatures are checked).
Which I don’t think necessarily invalidates the article (which I’ve only skimmed so far, but already strikes me as having a lot going for it), just some terminology used. It’s perfectly reasonable, regardless of terminology, to say: here are some techniques that encourage testability and high confidence in those tests. And it appears to me there’s a lot of that in the article. So with that said, I’m gonna go give it a more thorough read :)