I've been given the task of refactoring some legacy code, the main reason is to add unit tests (but I'm a firm believer that testable code is better code, so we're trying to reduce technical debt too). The current code is a big mess, there's a handfull of classes, one is 6000 lines, and has methods 300 lines long etc.
First thing I've been doing is splitting out data access for mocking, that's a nice independent thing. However, I've noticed that these classes, buy their nature, tend to have one 'entry' point, say a single method ProcessData
.
Theoretically this could be the only public method. But I definately want to test these methods independently:
public class DataProcessor {
public void ProcessData(...) {
// this is the 'enty point'
if (IsAlreadyProcessed())
return;
for (...) {
ProcessSubData(...)
}
}
public void ProcessSubData(...) {
if (IsDataTypeA)
ProcessWithMethodA(...);
else if (IsDataTypeB)
ProcessWithMethodB(...);
}
public bool IsAlreadyProcessed(...) {
// do some complex stuff here I want to test
...
}
public void ProcessWithMethodA(...) {
// something I definately want to test separately
}
public void ProcessWithMethodB(...) {
// something I definately want to test separately
}
}
Testing the 'root' method will be tricky, and involve some very hefty mock objects given the scope of all it's doing. Ideally I want to test the other methods, then just test that ProcessData
calls them.
Basically, it has a dependency on itself - should I inject a mock version of DataProcessor
into itself so I can test only sections of it?
The other option would be to split out the other Process methods into a separate class, and have that mockable and injectable into the DataProcessor
- but to do this for each 'level' that these methods call each other would require a few or more extra classes that only exist to explode it out so it can be tested.