I have a nontrivial service object developed with TDD. It started with a simple task: For an object from queue, construct an attempt for asynchronous processing. So I wrote a test around my constructAttempt()
method:
void constructAttempt() {...}
There are numerous possible scenarios that need to be taken into consideration, so I have a dozen tests for this method.
Then I implemented what I really needed it to do: Scan the whole queue and construct a batch of attempts. So the code looks more like:
public void go() {
for (QueuedItem item : getQueuedItems()) {
constructAttempt(item);
}
}
So I added a new test or two for this go()
method.
Finally I discovered I needed some preprocessing which sometimes may affect constructAttempt()
. Now the code looks more like:
public void go() {
preprocess();
for (QueuedItem item : getQueuedItems()) {
constructAttempt(item);
}
}
I have a few doubts about what I should do now.
Shall I keep the code as is, with constructAttempt()
, preprocess()
and go()
tested independently? Why yes/why not? I risk not covering side effects of preprocessing and break encapsulation.
Or shall I refactor my whole test suite to only call go()
(which is the only public method)? Why yes/why not? This would make tests a little bit more obscure, but on the other hand it would take all possible interactions into consideration. It would in fact become a black-box test using only the public API, what may not be in line with TDD.