Filed under: Gradle, JUnit, Mockito, TDD, — Tags: Hamcrest, IntelliJ IDEA — Thomas Sundberg — 2016-04-18
Ever included Mockito in your project and lost the nice feedback from Hamcrest?
And only when running your unit tests from IntelliJ IDEA? Instead of a message describing what
you should fix, you see java.lang.NoSuchMethodError: org.hamcrest.Matcher.describeMismatch
I have. More than once and been very frustrated. These are tools I like. Not getting good messages upsets me.
Unfortunately, Mockito re-packages Hamcrest and the human-readable messages are gone because of clashing versions.
It turns out that the order the dependencies are made available on the class path is the problem. Hamcrest is a transitive dependency to JUnit 4.12. When I looked at the class path used when I lost the messages, I noticed that Hamcrest was at the end. It would have great if it had been before Mockito. Now it is after and a method that JUnit tries to use to describe an error is not available.
Instead of depending on the transitive dependency from JUnit, I added an explicit dependency to Hamcrest and placed it early on the class path.
Instead of having my dependency section in Gradle like this:
dependencies { testCompile 'junit:junit:4.12' testCompile 'org.mockito:mockito-all:1.9.5' }
I added Hamcrest before JUnit and re-imported the project in InteliJ IDEA. This allowed me to force the order on the class path and the missing method was found.
dependencies { testCompile 'org.hamcrest:hamcrest-core:1.3' testCompile 'junit:junit:4.12' testCompile 'org.mockito:mockito-all:1.9.5' }
This is a hack but my frustration is gone and I'm not upset about a missing method any more.
It is problematic when popular tools like JUnit and Mockito depends on the same assertion framework but different versions. It is even more complicated when one of the dependencies is hidden by a re-packaging of Hamcrest.
Running from a command line doesn't re-produce the problem. It only appears when I run in IntelliJ IDEA.