Totally agree about the dissonance with TDD and it always surprised me it wasn't discussed more when TDD was going through the hard sell stage.
I guess my core problem is TDD only drives your design if you write quite granular tests but they then become barriers to further refactoring/redesign. However my current preferred approach (for anything non-trivial) is different to the authors. As he does I start out with outer-level acceptance-y tests, however those integration tests are then combined with extensive refactoring to drive the design, so I don't do the dreaming up of collaborators he does in step 4.
My reason for not thinking of collaborators early is although I think that approach has legs I found it didn't necessarily always the simplest/most elegant design you could come up with. I ended up encoding my first understanding of how to solve the problem into the interactions, even though I knew that my understanding of the problem at that point was much less than it would be once I dug a bit deeper.
Anyway with my current approach if I extract additional classes/whatever I might then test them directly, or use further tests to drive their design further (incl test doubles as appropriate). So I'll have one or a few tests of the extracted behavior at the outer level, and maybe more thorough testing at the lower level because quite often testing all the combinations and edge cases is easier at this level.
I guess my core problem is TDD only drives your design if you write quite granular tests but they then become barriers to further refactoring/redesign. However my current preferred approach (for anything non-trivial) is different to the authors. As he does I start out with outer-level acceptance-y tests, however those integration tests are then combined with extensive refactoring to drive the design, so I don't do the dreaming up of collaborators he does in step 4.
My reason for not thinking of collaborators early is although I think that approach has legs I found it didn't necessarily always the simplest/most elegant design you could come up with. I ended up encoding my first understanding of how to solve the problem into the interactions, even though I knew that my understanding of the problem at that point was much less than it would be once I dug a bit deeper.
Anyway with my current approach if I extract additional classes/whatever I might then test them directly, or use further tests to drive their design further (incl test doubles as appropriate). So I'll have one or a few tests of the extracted behavior at the outer level, and maybe more thorough testing at the lower level because quite often testing all the combinations and edge cases is easier at this level.