I find it a nice shortcut, but true as well than the mocking behavior can be non existent in the real code path.
Still, I reach out to mocking libraries often. Is that a bad practices and why ?
I find it a nice shortcut, but true as well than the mocking behavior can be non existent in the real code path.
Still, I reach out to mocking libraries often. Is that a bad practices and why ?
Mocks (or related techniques such as stubs, fakes) are useful when you have to interact with an outside system (e.g. send emails), for testing boundary conditions that are hard to replicate (what happens if an error is thrown), for highly generic code or, potentially, for really major architectural boundaries in your code base (but I feel that most people overestimate the confidence they have that they've determined the correct boundaries).
For anything else, I'd prefer to isolate pure code from code with side effects as much as possible so that the former can be unit tested without any dependencies (even if one class/module/whatever calls another, it doesn't have to be mocked out), and the latter is mostly just wiring that can be tested through a combination of integration testing and maybe some occasional use of a mock here and there.
Unfortunately not many code bases are structured that way, so you'll have to pick your battles and maybe live with more (brittle) mocks than you'd like - or with slower and more flakey (integration) tests that you'd like.
The issue is that if you need to mock then your design is not really properly decoupled. The mock bakes in assumptions about your program state - which may or may not hold up in the real world. This ends up creating a sort of invisible coupling to whatever will be creating/updating the state in the real world
The terminology is a bit fuzzy b/c the author describes his unit tests as using mocks - but to me that's not a unit test - that's an integration test..
At the end of the day you do need some coupling and some integration tests are inevitable - but the idea is that TDD pushes you to minimize that
Would love to hear anyone's corrections :)
Otherwise your mocks may end up driving the system to a state that is never actually encountered in production, while the unit test still passes. When you run an integration test or a real build of the application, the actual system itself will fail to behave as expected.
The mock implementations can diverge from the actual production behaviour.
I think Martin Fowler has a nice dichotomy where he splits tests up into solitary (generally using mocks for deps) and sociable (generally using real code for dependencies): https://martinfowler.com/bliki/UnitTest.html
I've seen people have problems with mocks when they have poorly designed code that demands Byzantine test setups. The "bad mocks" smell usually means the production code is due for a refactor. (So let's hope you have behavioral tests and not implementation-only tests to help everyone refactor.)
The customer always uses software in some unexpected way, but we don't defer all "testing" to just watching the customer interact.
Testing is to give developers the fastest, most meaningful, most actionable feedback about their code changes so that they can make better decisions.
Customer issues are not the only things we're worried about. And software seems to be usable and make plenty of money even when users see something screwy once in a while.