Tue 20 Jul 2010
An Easy Way to Test Abstract Classes with Mockito
One problem that you may have encountered when attempting to write a test for an abstract class is that, well, you can’t instantiate it. So how do you test it?
I was wondering the same thing a few weeks ago. I had the following abstract class (simplified for readability and understanding):
public abstract class MyAbstractClass {
protected String getDefaultOrder() {
return getDefaultFetch().split(",")[0];
}
protected abstract String getDefaultFetch();
}
I wanted to write a simple test that would verify that getDefaultOrder() would perform as expected and return the first word in the comma-delimited string returned by getDefaultFetch().
Luckily, I stumbled upon Mockito’s thenCallRealMethod() method. This made the test easy to write:
public void defaultOrderShouldBeFirstWordInDefaultFetch() {
MyAbstractClass abstractClass = mock(MyAbstractClass.class);
when(abstractClass.getDefaultFetch()).thenReturn(
"Rank,FormattedID,Name,PlanEstimate,Priority,Owner,ClosedDate,CreationDate"
);
when(abstractClass.getDefaultOrder()).thenCallRealMethod();
assertEquals(abstractClass.getDefaultOrder(), "Rank");
}
As you can see, we’re telling Mockito that when the getDefaultOrder() method gets called on the mock object “abstractClass”, Mockito should execute the real getDefaultOrder() defined in our MyAbstractClass class. This is contrary to Mockito’s default behavior of simply returning the default value for the return type of the method called on the mock object (in this case, for getDefaultOrder()’s return type of String, Mockito would return null).
So there you go: an easy way to test methods in abstract classes!

Thanks for posting this trick.
At first I was thinking why would you want to test an abstract class in this manor. I can see it being useful if the classes that are being built off this base are not ready when you have test it, but why wouldn’t you just use a stubbed out class that implements the Abstract operations?
I guess there is some effort and risk involved with creating and testing an object that will not be part of the baseline, but doesn’t Stub allow you to test with it within Mockito and possibly use it else where until the official implementation is ready?
It all probably depends on the situation.
The main arguments I can think of against using a stubbed out class that implements the abstract operations are decreased readability and an increase in the amount of code that needs to be written to write the test.
.
I suppose it is a little weird mocking the class that you’re writing tests against, but it still seems cleaner than the alternative.
Like you said, it probably depends on the situation, just like everything else