Java Hamcrest:Collection包含类型的项目

Mar*_*itt 20 java unit-testing hamcrest

我想声明它List<Achievement>包含一个类型的成员TestAchievement.

这是我的断言:

List<Achievement> achievements; // Populated elsewhere
assertThat(achievements,hasItem(isA(TestAchievement.class)));
Run Code Online (Sandbox Code Playgroud)

这不编译,报告错误:

方法断言Assert类型中的(T,Matcher)不适用于参数(List,Matcher <Iterable <TestAchievement >>)

使用Hamcrest这种断言的正确语法是什么?

Mar*_*itt 21

谢谢你的帮助.

这里的帖子暗示这是Hamcrest的一个缺陷,所以我前往hacmrest网站注册一个bug,我发现我使用的mvn/ivy依赖声明已经过时,给我一个旧版本Hamcrest.

1.1中存在此错误,如果使用声明,则是最新的错误

<dependency org="org.hamcrest" name="hamcrest-all" rev="1.1">
Run Code Online (Sandbox Code Playgroud)

但是,正确的依赖声明是:

<dependency org="org.hamcrest" name="hamcrest-library" rev="1.3.RC2"/>
Run Code Online (Sandbox Code Playgroud)

更新到此解决了这个问题.我的测试中使用的语法是:

 assertThat(achievements, hasItem(isA(TestAchievement.class)));
Run Code Online (Sandbox Code Playgroud)

  • 在我最终偶然发现固定的更新版本之前,我花了近一个星期的时间对Hamcrest库代码中的错误声明问题进行了一次.只是坚果!事情不应该是这么复杂. (2认同)

Mik*_*der 9

Java 6中存在与此相关的错误.

此代码将抛出各种错误,例如"找不到符号......"

assertThat(achievements, hasItem(isA(TestAchievement.class)));
Run Code Online (Sandbox Code Playgroud)

解决此问题的方法是将匹配器声明为变量,然后引用该变量.重要的是要注意变量的类型,特别是泛型部分,对于它来说非常重要.

Matcher<Iterable<? super TestAchievement>> matcher = hasItem(isA(TestAchievement.class));
assertThat(achievements, matcher);
Run Code Online (Sandbox Code Playgroud)

有趣的是,如果你使用instanceOf()而不是isA()你再次遇到问题.(尽管如果你忽略这些警告,无论如何这可能对你有用.)扩展你以前的修复,你可以使用:

Matcher<TestAchievement> itemMatcher = Matchers.instanceOf(TestAchievement.class);
Matcher<Iterable<? super TestAchievement>> matcher = hasItem(itemMatcher);
assertThat(achievements, matcher);
Run Code Online (Sandbox Code Playgroud)