I have created a new class which extends a 3rd party abstract class. The new class calls methods in the abstract class. The problem I have is when trying to write the unit test, I'm not sure how to write a test as I would not know the exact details the 3rd party class requires.
The AbstractDecoratorMapper below is a SiteMesh specific class which I have to extend for SiteMesh to work correctly. As far as I can tell from the documentation I can't use composition.
public final class PartnerDecoratorMapper extends AbstractDecoratorMapper {
@Override
public void init(Config config, Properties properties, DecoratorMapper parent) throws InstantiationException {
super.init(config, properties, parent);
}
@Override
public Decorator getDecorator(HttpServletRequest request, Page page) {
if (super.getDecorator(request, page).getName().equalsIgnoreCase("default")) {
return getNamedDecorator(request, "externalPartnerDefault");
}
return super.getDecorator(request, page);
}
}
I use JMock if there is anything this tool can do to help.
If you really need to extend the base class to override something, extract the functionality to a third class and make the extended class a proxy. The extended class does nothing else than call methods on the third class. E.g. This way, you can test the real implementation, without instantiating the base class.
Unit testing abstract classes leads to the same consequences as unit testing private methods. In fact, these two practices are essentially the same anti-pattern. Both couple your tests to implementation details and therefore increase the noise you have to deal with after each refactoring.
Whenever you're testing a subclass of your base class, have your test class inherit from your test superclass.
Also, writing unit tests for abstract class methods is as important as for normal classes and methods. We can test each of them using different techniques or different test support libraries available.
You don't need to know details from 3rd party libs... you just need to mock them returning something you expect from them.
In the case you are inheriting it you could setup the class as it will be used on production and invoke the methods that should be invoked in regular uses. All that you need to check is if the result is as you expect. (you don't need to know exactly how the 3rd party classes works on the test).
In order to check if all code you implemented was executed you can use a plugin to check the coverage like eclemma - http://www.eclemma.org/ )
With JMock, you can't to the best of my knowledge mock calls to a superclass of the class under test.
The answers to this related question may be useful, but the main answer is to switch to a mocking framework (JMockit is suggested) that does support this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With