Sunday, 6 May 2012
Java, PowerMock and the slow death of pointless Interfaces
Back in the day, say around 2000, the use of Java interfaces were pushed as the one true way (tm) for expressing dependecies between classes. The established wisdom was that if one class needs another then it should be expressed as a dependency on an interface. There are two advantages to expressing dependencies via interfaces: (1) you can have a test implementation of the interface so you can unit test a class without using the real dependency (2) you can have multiple implementations of the interface, which might be chosen at runtime. In practice, (2) happens quite rarely, but remains a completely valid case for interfaces use.
And so, the wisdom went, you were condemned to eternal damnation called a static method on another class. A call to a static method is hard wired like concrete and steel. No way to stub it out for unit testing.
Enter PowerMock in about 2008/2009 which works with EasyMock or Mockito and which allows you to mock pretty much anything:
"PowerMock is a framework that extend other mock libraries such as EasyMock with more powerful capabilities. PowerMock uses a custom classloader and bytecode manipulation to enable mocking of static methods, constructors, final classes and methods, private methods, removal of static initializers and more. By using a custom classloader no changes need to be done to the IDE or continuous integration servers which simplifies adoption. Developers familiar with the supported mock frameworks will find PowerMock easy to use, since the entire expectation API is the same, both for static methods and constructors. PowerMock aims to extend the existing API's with a small number of methods and annotations to enable the extra features. Currently PowerMock supports EasyMock and Mockito."
I have seen PoweMock used a lot in several organizations. It just works(tm). I have noticed that it simplifies the way people write code.
So, with PowerMock in hand, here is some advice for writing Java, that goes against established wisdom.
1) Don't write to interfaces unless you really need multiple implementations! Why create an interface and a class when just a class will do? If you find you really need an interface later then create one and use it. But remember most of the time, YAGNI for unit testing thanks to PowerMock. (where YAGNI means "you ain't gonna need interfaces" as opposed to the more traditional "you ain't gonna need it".)
2) Use EasyMock or Mockito for unit testing and the extras that PowerMock gives you if you need to. (I have nothing against JMock, and perhaps JMock has the equivalent features that PowerMock provides. )
3) Do not be afraid to use static methods if appropriate. When is appropriate? Now there's a question Rich Hickey would be happy to answer.
Thanks to PowerMock, we are free to use interfaces where they are really needed.
Subscribe to:
Post Comments (Atom)
3 comments:
YAGNI needs to be weighed against ISP however. It can payoff to decouple large classes with a small interface for refactoring and understanding later. Needing to mock static or private methods can be a code smell but I agree not in all cases.
Fair point, but I'd argue that the simplesst possible "interface" to the dependency is defined by suitable use of public vs private/protected methods in the concrete class. ("interface" in this context is used in the generic sense)
Interface Segregation Principle (ISP)
The dependency of one class to another one should depend on the smallest possible interface.
Post a Comment