Thursday, 5 August 2010

Overriding selective methods in order to unit test

Today I was trying to test a taglib that was quite old and structured in a way that didn't make testing easy. The class under test was pretty simple, but it called a method in its parent which was quite complicated and made for extensive setup for each test. It occurred to me that if I just override that other method - not the one I was trying to test - it would make my life a lot easier.



The code I had was something like this:



public class MyTag {
public void doStart() {
try {
MyObject ob = hardToTestMethod();

if (ob.doSomethingState()) {
// do something
} else {
// do something else
}

} catch (Exception e) {
throw new JspException("something went wrong", e);
}
}
}

Which gave me 3 use cases: an exception is throw, MyObject is returned in a doSomethingState or not. Inline we can easily override the hardToTestMethod to throw an exception or a mock object, using your favourite mock lib.



@Test(expected = JspException.class)
public void doStart_ThrowsAnException() {
MyTag tag = new MyTag() {

@Override
public MyObject hardToTestMethod() {
// or you could return a mock
throw new RuntimeException("I'm on a boat yo!");
}
};
tag.doStart();
}


I felt all clever. At that point I knew that this must be a well known technique. The closest thing that I found with a couple of minutes of searching is an IBM article from 2002 which talks about refactoring factory code. Not exactly the same thing, but close enough. I just thought that I would share in case other people were dealing with difficult to test java and wanted to know another technique to be able to unit test it.



No comments:

Post a Comment