我想断言List<Achievement>
包含TestAchievement
类型的成员。
这是我的断言:
List<Achievement> achievements; // Populated elsewhere
assertThat(achievements,hasItem(isA(TestAchievement.class)));
这不编译,报告错误:
方法断言(T,Matcher) 在Assert类型中不适用 为参数(List, 匹配&LT;可迭代&LT; TestAchievement&GT;&GT)
使用Hamcrest进行此类断言的正确语法是什么?
答案 0 :(得分:21)
感谢您的帮助。
这里的帖子暗示这是Hamcrest的一个缺陷,所以我前往hacmrest网站注册一个bug,我发现我使用的mvn / ivy依赖声明是过时的,给了我一个旧版的Hamcrest。
这个错误存在于1.1,这是使用
声明的最新错误<dependency org="org.hamcrest" name="hamcrest-all" rev="1.1">
但是,正确的依赖声明是:
<dependency org="org.hamcrest" name="hamcrest-library" rev="1.3.RC2"/>
更新到此解决了这个问题。我的测试中使用的语法是:
assertThat(achievements, hasItem(isA(TestAchievement.class)));
答案 1 :(得分:9)
Java 6中有一个bug与此相关。
此代码会抛出各种错误,例如“找不到符号......”
assertThat(achievements, hasItem(isA(TestAchievement.class)));
解决此问题的方法是将匹配器声明为变量,然后引用该变量。重要的是要注意变量的类型,特别是泛型部分,对于它来说非常重要。
Matcher<Iterable<? super TestAchievement>> matcher = hasItem(isA(TestAchievement.class));
assertThat(achievements, matcher);
有趣的是,如果您使用instanceOf()
代替isA()
,则会再次遇到问题。 (尽管如果你忽略了警告,这可能对你有用。)扩展你可以使用的上一个修复:
Matcher<TestAchievement> itemMatcher = Matchers.instanceOf(TestAchievement.class);
Matcher<Iterable<? super TestAchievement>> matcher = hasItem(itemMatcher);
assertThat(achievements, matcher);
答案 2 :(得分:3)
assertThat(achievements, hasItem(
IsInstanceOf.<Achievement>instanceOf(TestAchievement.class)));
答案 3 :(得分:3)
我一直在与此作斗争一段时间,这里的方法都没有真正达到预期效果。出于纯粹的绝望,我尝试转换为数组,看看是否有所作为:
List<Object> listOfThings = (List) someService.findThings(); // your business logic here
Object[] arrayOfThings = listOfThings.toArray(new Object[listOfThings.size()]);
assertThat(arrayOfThings, hasItemInArray(instanceOf(SpecialThing.class)));
它确实有所作为。现在我的测试完美无瑕。复制到阵列的一行似乎是一个合理的权衡,以节省大量的麻烦。
答案 4 :(得分:2)
我一直在讨论这个问题,似乎我知道的唯一方法是将List<Achievement>
转换为List<Object>
。问题是CoreMatchers.instanceOf()
返回Matcher<Object>
。
通过这种修改,我能够让它发挥作用: -
List<Object> achievements = new ArrayList<Object>();
achievements.add(new Achievement());
achievements.add(new TestAchievement());
assertThat(achievements, hasItem(instanceOf(TestAchievement.class)));
答案 5 :(得分:2)
assertThat(T actual, Matcher<? super T> matcher)
所以问题是你的匹配器是Matcher<TestAchievement>
,而不是适用于任何超类或成就接口实例的匹配器。
看起来instanceOf
匹配器只有一个错误的类型绑定。
您可以通过执行类似
@SuppressWarnings("unchecked")
Matcher/*no_param*/ isATestAchievement = instanceOf(TestAchievement.class);
assertThat(..., isATestAchievement);
答案 6 :(得分:2)
Actuall它不适用于更复杂的Matcher,即使使用最新版本。
assertThat(result.getAnswers(),
Matchers.hasItem(Matchers.hasProperty("content")));
它不起作用,你会得到:
方法断言Assert类型中的(T,Matcher)不适用于参数(Set,Matcher&gt;)
您可以通过将其转换为数组来解决它:
assertThat(result.getAnswers().toArray(), hasItemInArray(Matchers.hasProperty("content", equalTo("<h4>new comment</h4>"))));