hamcrest和mockito的冲突

现在测试驱动开发已经是主流,大多数主流的技术平台都把更好的支持单元测试作为吸引开发者的一个要件。Java里自然不例外。JUnit似乎已经够好了,但是还是有人觉得它的断言部分太难用,表达起来不顺畅,所以就有了Hamcrest。不幸的时JUnit 4.11之前的版本和不太hamcrest合作,它只内置了一个更旧的hamcrest和单独hamcrest包经常起冲突。典型症状是:

java.lang.NoSuchMethodError: org.hamcrest.Matcher.describeMismatch(Ljava/lang/Object;Lorg/hamcrest/Description;)V
	at org.hamcrest.core.IsCollectionContaining.matchesSafely(IsCollectionContaining.java:31)
	at org.hamcrest.core.IsCollectionContaining.matchesSafely(IsCollectionContaining.java:14)
	at org.hamcrest.TypeSafeDiagnosingMatcher.matches(TypeSafeDiagnosingMatcher.java:55)
	at org.hamcrest.core.AllOf.matches(AllOf.java:24)
	at org.springframework.test.util.MatcherAssertionErrors.assertThat(MatcherAssertionErrors.java:62)
	at org.springframework.test.web.servlet.result.ModelResultMatchers$1.match(ModelResultMatchers.java:56)
	at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:148)
	

 后来JUnit 4.11做出了正确的决定,不在内置hamcrest,而是利用包管理工具来声明对相应hamcrest的依赖。这样就彻底消除class文件的新旧版本冲突问题。

Mockito是个很有用的mock对象生成工具,很多单元测试使用mock对象可以事半功倍。所以Mockito的出现给广大码农带来了福音。不过你要和hamcrest合用,那么上面的类文件冲突又要找到上门来了。原因还是mockito-all早期版本捆绑了hamcrest。以下JUnit,Hamcrest和Mockito版本组合是兼容的:

  • JUnit 4.11
  • hamcrest-core 1.3
  • mockito-core 1.10.19

为方便懒人,附上Gradle的依赖声明:

 testCompile "junit:junit:4.11"
 testCompile "org.mockito:mockito-core:1.10.19"

hamcrest-core1.3是JUnit 4.11自动依赖的,Gradle能够识别这样所谓传递式依赖(transive depedency),所以没有必要声明hamcrest-core。

 

最后,作为总结,在一个模块化的世界里,作为一个类库的开发者,请不要捆绑发布你无法控制的依赖,因为你往往无法跟上上游版本的节奏,但是使用者却很可能需要更新的上游版本。

你可能感兴趣的:(mockito)