Point of testing units and components before whole system is to localize bugs BEFORE they damaged some unrelated part of the system, causing confusing red herring error. If you mock the surroundings of a component, you eliminated moving parts - and localized the bug.
Of course you need to weight the effort to mock: because it is code, it will have bugs and will have to be maintained too, if parts of the system it mocks are in flux.
As always in engineering, it is about finding the right compromise between competing interests within limits you are facing.
Decision to mock such externality (or not) depends on many factors:
- Does external module adds time delay? If so, mocking it with canned answer might improve speed of unit testing. If not, and module has strong unit tests, you may want to keep real thing.
- Does calling external interface changes global status, like database changes? Will you keep the changes, or restore database (which takes time)?
- Was your system designed to mock certain external interface? If not, is it worth to add complexity, possibly breaking working code?
- If interface is to outside vendor who is very cooperative and has special QA subsystem for you to test, even keeping such externality might make sense, even with delay. Or crudely mock such service for developers, and use real thing for higher tests.
You need to pick your battles, use limited resources wisely. Where do you have more spare resources:
- developers, to create advanced mock,
- sysadmin, to create complicated multilayer system, with different levels of mocking, and deploying right code in right layer
- QA team time and focus, manually analyzing logs and tracebacks for errors
- QA developing custom tools fit your exact process (we use this approach a lot, low-hanging fruits because all is so custom)
- money to buy more servers to run continuous integration tests in close-to-real-production environment, even if slower (and with risk of red herring error message). Servers are cheap (compared with cost of sysadmin's time needed to administer complicated multilayer system) - it is single-time decision.
You will NOT be able to cover all bugs by single approach. Instead, think about using multi-layer defense like Swiss cheese with holes: one slice has holes in it, but if you place multiple layers of cheese, and every layer has holes in different area, together they will cover sandwich without holes.