There are Java constructs well known for their testability issues:
- Private methods
- Static methods
- Final methods or classes
A skilled Java developer following TDD will try to minimize their testability impacts. Don't know about techniques to enhance testability? They are explained well on Misko Hevery's blog.
Some developers argue that we have frameworks today (like PowerMock or JMockIt) that are able mock these testability killers, and it's true. So should we throw factory methods to bin and start using static or singleton classes widely? The answer is NO. The reason is in Java language nature. There isn't way how to mock mentioned constructs using Java features like inheritance, polymorphism, or reflection. Byte-code manipulation is needed. And that is the problem.
Here are some facts about PowerMock:
- It is using Javassist library for byte-code manipulation
- It took to 1.5 years to make PowerMock + Javaassist compatible with Java7 since its introduction. Here is note from PowerMock change log:
Change log 1.5 (2012-12-04) --------------------------- Upgraded to Javassist 3.17.1-GA, this means that PowerMock works in Java 7!
- PowerMock site says: "Please note that PowerMock is mainly intended for people with expert knowledge in unit testing. Putting it in the hands of junior developers may cause more harm than good".
- Here is conversation about unsuccessful attempt to use Javasisst with Java8
I tried to use PowerMock and JMockIt to test some legacy code. The result weren't acceptable for me. Sometimes there were some strange crashes or clash with JaCoCo test coverage tool (have to say that I didn't give JMockIt deep chance and abandoned on it immediately after first problems). At the end I always decided to change the production code to enhance testability and use plain Mockito.
If it would be up to me I would exclude byte-code manipulation testing frameworks from technology stack completely. Java8 is coming soon and potential migration of unit tests can be a big problem if it is used widely. It would be ridiculous to wait 1.5 years for Java8 update because of testing framework.
I respect PowerMock and JMockIt projects and people behind them. They are sometimes valuable in cases when you have to deal with legacy code or third party libraries.