I'm not suggesting middle layer testing is not valuable, shouldn't be done, or to never use mocks, etc., it is just much more difficult and more creativity is required to add value in this area. For example, in some situations middle layer testing requires the creation of various kinds of utilities and frameworks in order to find a reasonable benefit vs effort sweet spot. Dogmatic approaches (such as mocking all dependencies in all situations) feel like they are productive at first but can end up being costly as each mock is an alternate implementation of an interface and doesn't necessary capture the behaviour of the concrete implementation.
I don't strive for 100% coverage and I hardly ever do TDD unless I'm working on something hard to solve.
Tests give me confidence and results in less time repeating the feedback loop. I might have a slower "coding speed" but I have fewer regressions during refactoring. Less bugs to fix while iterating. And less back and forth with stakeholders to ship something. Overall I'm way faster with tests than without.
1. Feel free to write tests that help you develop your thought or solution. Not all of those should be checked in
2. Ask yourself: “What test do you need to write in order to protect this code from your future self next year when you have forgotten everything about this?”
Tests force you to write better code. Code that is easier to change. Code that is more robust.
You don't need 100% coverage or perfect tests to gain this benefit.
A good test suite enables you to make large refractors safely and quickly.
The most scary refractors I've ever had to do are ones that involve large changes to code that has no tests.
Often those refractors that allow company level pivots require adding huge amounts of tests to a legacy code base before I can even get started.
Adding tests to code that has none is the worst. The code is coupled all over the shop and requires 100 times more mocking and stubbing to get under tests when you add this stuff retroactively.
Tests speed up development velocity and improve your codebase.
Just don't get stupid about it and you won't negatively impact startup performance.