by JNRowe on 6/16/25, 1:04 AM with 19 comments
by hamstergene on 6/18/25, 9:31 AM
It makes so much more sense this way:
- users don’t have to duplicate effort of writing more or less same mock/stub of the same library
- mock is forced to be up to date, because the library’s maintainers probably pay more attention to their release notes than you do
- no one knows the best choice of mocking approach/DSL than the library’s authors
- the adoption of inversion of control / dependency injection and comprehensive testing could be so much wider if writing a test didn’t require first solving an extra problem if how to mock something with complicated API and if it worth solving in the first place
by molf on 6/18/25, 9:30 AM
If you care about being alerted when your dependencies break, writing only the kind of tests described in the article is risky. You’ve removed those dependencies from your test suite. If a minor library update changes `.json()` to `.parse(format="json")`, and you assumed they followed semver but they didn’t: you’ll find out after deployment.
Ah, but you use static typing? Great! That’ll catch some API changes. But if you discover an API changed without warning (because you thought nobody would ever do that) you’re on your own again. I suggest using a nice HTTP recording/replay library for your tests so you can adapt easily (without making live HTTP calls in your tests, which would be way too flaky, even if feasible).
I stopped worrying long ago about what is or isn’t “real” unit testing. I test as much of the software stack as I can. If a test covers too many abstraction layers at once, I split it into lower- and higher-level cases. These days, I prefer fewer “poorly” factored tests that cover many real layers of the code over countless razor-thin unit tests that only check whether a loop was implemented correctly. While risking that the whole system doesn’t work together. Because by the time you get to write your system/integration/whatever tests, you’re already exhausted from writing and refactoring all those near-pointless micro-tests.
by eximius on 6/18/25, 8:15 AM
Real object where practical, fakes otherwise, mocks only as required for exceptional circumstances.
Works great in interconnected monorepos where you can provide high fidelity fakes of your services for other integrating teams to use in their tests. Often our service fakes are literally just the real service wrapped with an injected fake DB/store.
by AugustoCAS on 6/18/25, 8:09 AM
The saddest one I saw was a team trying to do functional programming (with Spring). The tech lead was a bit flummoxed when I asked why mocks are not used in functional languages and continued to think that 'mocking functions' is the correct way to do TDD.
by fellatio on 6/18/25, 7:53 AM
by lmm on 6/18/25, 9:23 AM
by strken on 6/18/25, 9:30 AM
It sounds like it's more about wrapping awkward APIs instead of calling them directly. Yes, this is good advice! But it only tangentially has anything to do with mocking.
by ramchip on 6/18/25, 12:10 PM
by mpweiher on 6/18/25, 8:04 AM
"Well, it's impolite, isn't it?"
by hmmokidk on 6/18/25, 2:51 PM
by gnabgib on 6/16/25, 1:08 AM