> Dependency injection leads to elaborate, brittle fixtures
I believe that can happen, but personally (N=1) haven't seen it. If anything, (well-done) DI is supposed to prevent that, b/c fixtures are isolated instead of depending on random global behavior.
That said, I also don't like Spring/Guice/Dagger auto-wiring DI (somewhat guessing that is what caused your headaches), and instead just create an "AppContext" type with all of the applications "singletons" and pass that around.
Granted, it's still global-ish, so maybe I'm cheating, but its nicer IMO than module hacks.
> I use mocks to arrange state A without going through
> all the business rules involved in creating state A
I like tests being able to immediately jump to state A, but fwiw don't see why mocks would be needed to do so.
I do agree re avoiding test explosion/transitivity, and a few functional happy/sad plumbing tests, but again seems orthogonal to state/mock.
> You end up with elaborate, (often custom), mocks that
> couple all of the tests together in hard to maintain ways
Totally agreed. Another -1 for mocks. :-) I.e. with state-based you should be able to test "end-to-end" (with state-based / in-memory stubs for your input/output data stores/etc.) without any of "oh right, copy/paste these 5 lines of 'when method X return result Y' for ~2-5 some mocked-out calls).
(And, to be pedantic, if you mean something other than 'when method X return result Y' for the term 'mock', then we're probably talking about different things.)