Hi Esko,
Sorry this is quite off-topic. You (Esko) seem to have a very clear grasp
on the definitions used in your reply which made it a bit confusing to
interpret your message.
In particular I'm referring to the following definitions:
- Test-first
- Mutation testing
- Test-after
I often can't really tell the difference between them. Would you hazard a
guess to their definitions?
I hope my reply doesn't take too much away from Kaleb's original post about
avoiding mocking helper-classes, an issue I've bothered with as well!
Regards,
Niels
2012/9/10 Esko Luontola <esko.luontola@...>
**
Kaleb Pederson wrote on 10.9.2012 19:39:
When I end up splitting a class, I've usually introduced another
collaborator and I need to do exactly what you describe here. That is,
I change each of the tests to use a mock for the newly introduced
collaborator.
Sometimes, the new collaborator is a helper or infrastructure-based
collaborator. That is, it's intended to make the code cleaner and
more reusable without actually changing the observable behavior. In
this case, the changes I've made would be considered "implementation
details," and I leave all the existing tests but introduce a new test
class for the new collaborator. In this case, the original class will
use the helper directly and I avoid mocking it out.
I'm doing it similar to Kaleb.
After extracting the new class, I look at its code to see what are its
responsibilities/features, and then write tests for each feature that I
see. Through lots of TDD experience I'm able to know what tests I would
have written for it test-first, so I can write pretty much the same
tests test-after (maybe even better tests, because now I know exactly
what the code does; test-first needs some more test refactoring). Or if
it's easier, I'll refactor and move the old tests which cover the
extracted responsibilities.
After the new class has its tests in place, I have a look at the old
tests. If the responsibility was moved to the new class, I remove the
test. If a test can be made simpler by replacing the new class with a
test double, then I do it. Or if the tests are written in terms of the
old class and the extracted class is just an implementation detail, then
I keep the tests as-is.
As a safety net I use for mutation testing. That will
let me find missing tests, in case I missed some corner case when doing
test-after. It might also be useful to run just the new tests and see
now well they cover the new class (though I'm not yet doing it - maybe
after there is an IDE plugin for PIT).
--
Esko Luontola
www.orfjackal.net
[Non-text portions of this message have been removed]