Given: A LegacyControllerClass
that extends a MonsterFrameworkClass
(part of a very yucky framework that people are just living with for years). Framework class does lots of magic ranging from tons of logic in the default constructor to static blocks that reflectively load classes.
Lots of life-cycle methods in LegacyControllerClass
, which mutate global states. The execute()
method is a thousand-liner that has all the evils that you can think of.
public class LegacyControllerClass extends MonsterFrameworkClass {
//Life-cycle method
public void validate(){...}
//Life-cycle method
public void preExecute() {...}
//Life-cycle method
public void execute() {
//oodles of legacy code here:
// examples: call static methods of 'Util' classes
// lots of new X().y(..)
// call databases, services
// Even call super.execute()!!
// More rubbish
// More rubbish
}
}
Okay, now the scene of action is the execute() method. I'm introducing Test-Driven-Development to these have-nots, by test-driving an item what they call as a 'story'. The 'story' involves adding an error message to the responseProperties so that the view(jsp) can read it off and display. The pseudo-code is something like:
if (error) {
Build the error message
Add the error message into the responseProperties
}
This code unfortunately has to be sand-witched between the rubbish in the execute()
method.
My question is: what is the best thing I can do? The solution I could come up is:
- extracting two methods
rubbish1()
andrubbish2()
- stub them out in my test code with whatever expectations (Eg;- set the error flag)
- Put my code between
rubbish1()
andrubbish2()
I started implementing it this way, but the MonsterFrameworkClass
is really getting in my way: like static loads, constructor magic that loads up a ResourceBundle
of random properties files, etc.
Are there alternate ways of dealing with the same?
Teeny-tiny Disclaimer: I am definitely going to buy Michael Feather's "Working with Legacy Code" and gulp it down, but SO seemed to be a low-hanging fruit.