Java Hamcrest:集合包含类型的项目

发布于 2024-10-16 22:13:28 字数 468 浏览 8 评论 0 原文

我想断言 List 包含 TestAchievement 类型的成员。

这是我的断言:

List<Achievement> achievements; // Populated elsewhere
assertThat(achievements,hasItem(isA(TestAchievement.class)));

这不会编译,报告错误:

方法assertThat(T, Matcher) 在断言类型中不适用 对于参数(列表, Matcher>)

使用 Hamcrest 的此类断言的正确语法是什么?

I'd like to assert that List<Achievement> contains a member of type TestAchievement.

Here's my assertion:

List<Achievement> achievements; // Populated elsewhere
assertThat(achievements,hasItem(isA(TestAchievement.class)));

This doesn't compile, reporting the error:

The method assertThat(T, Matcher)
in the type Assert is not applicable
for the arguments (List,
Matcher<Iterable<TestAchievement>>)

What's the correct syntax for this type of assertion using Hamcrest?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

£冰雨忧蓝° 2024-10-23 22:13:28

感谢您的所有帮助。

这里的帖子表明这是 Hamcrest 的一个缺陷,所以我前往 hacmrest 网站注册一个错误,同时我发现我使用的 mvn / ivy 依赖声明已经过时,给了我一个旧版本汉克雷斯特。

此错误存在于 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)));

Thanks for all the help.

The posts here suggested it was a defect with Hamcrest, so I headed over to the hacmrest site to register a bug, whien I discovered that the mvn / ivy dependency declaration I was using was out-of-date, giving me an old version of Hamcrest.

This bug exists with 1.1, which is the latest if declared using

<dependency org="org.hamcrest" name="hamcrest-all" rev="1.1">

However, the correct depedency declaration is:

<dependency org="org.hamcrest" name="hamcrest-library" rev="1.3.RC2"/>

Updating to this solved the issue. The syntax used in my test is:

 assertThat(achievements, hasItem(isA(TestAchievement.class)));
冷…雨湿花 2024-10-23 22:13:28

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);

There is a bug in Java 6 that relates to this.

This code will throw various errors such as "cannot find symbol..."

assertThat(achievements, hasItem(isA(TestAchievement.class)));

The work around for this is to declare the matcher as a variable and then reference that variable. It is important to note that the type of the variable, specifically the generics section, is very important for this to work.

Matcher<Iterable<? super TestAchievement>> matcher = hasItem(isA(TestAchievement.class));
assertThat(achievements, matcher);

Interestingly if you use instanceOf() instead of isA() you once again run into issue. (although if you ignore the warnings this might just work for you anyway.) Expanding on the previous fix you can use:

Matcher<TestAchievement> itemMatcher = Matchers.instanceOf(TestAchievement.class);
Matcher<Iterable<? super TestAchievement>> matcher = hasItem(itemMatcher);
assertThat(achievements, matcher);
川水往事 2024-10-23 22:13:28
assertThat(achievements, hasItem(
    IsInstanceOf.<Achievement>instanceOf(TestAchievement.class)));
assertThat(achievements, hasItem(
    IsInstanceOf.<Achievement>instanceOf(TestAchievement.class)));
东风软 2024-10-23 22:13:28

我已经为此奋斗了一段时间,这里的方法都没有真正达到预期的结果。出于纯粹的绝望,我尝试转换为数组,看看这是否会产生影响:

List<Object> listOfThings = (List) someService.findThings(); // your business logic here
Object[] arrayOfThings  = listOfThings.toArray(new Object[listOfThings.size()]);

assertThat(arrayOfThings, hasItemInArray(instanceOf(SpecialThing.class)));

它确实产生了影响。现在我的测试完美无缺。一行复制到数组似乎是一种合理的权衡,可以节省很多麻烦。

I've been battling with this for a while, none of the approaches here really had the expected result. Out of pure despair I tried converting to an array to see if that made a difference:

List<Object> listOfThings = (List) someService.findThings(); // your business logic here
Object[] arrayOfThings  = listOfThings.toArray(new Object[listOfThings.size()]);

assertThat(arrayOfThings, hasItemInArray(instanceOf(SpecialThing.class)));

And it did make a difference. Now my test works flawlessly. The one line of copy-to-array seems to be a reasonable trade-off to save a lot of hassle.

涙—继续流 2024-10-23 22:13:28

我已经对此进行了一段时间的研究,似乎我知道的唯一方法是将 List 转换为 List。问题是 CoreMatchers.instanceOf() 返回 Matcher

通过修改,我可以让它工作:-

List<Object> achievements = new ArrayList<Object>();
achievements.add(new Achievement());
achievements.add(new TestAchievement());
assertThat(achievements, hasItem(instanceOf(TestAchievement.class)));

I have been futzing around with this for awhile, and it seems like the only way I know is to convert List<Achievement> to List<Object>. The problem is CoreMatchers.instanceOf() returns Matcher<Object>.

With that modification, I'm able to get this to work:-

List<Object> achievements = new ArrayList<Object>();
achievements.add(new Achievement());
achievements.add(new TestAchievement());
assertThat(achievements, hasItem(instanceOf(TestAchievement.class)));
流年里的时光 2024-10-23 22:13:28

实际上,即使使用最新版本,它也不适用于稍微复杂一点的匹配器。

assertThat(result.getAnswers(),
            Matchers.hasItem(Matchers.hasProperty("content")));

它不会工作,你会得到:

Assert 类型中的方法assertThat(T, Matcher) 不适用于参数(Set, Matcher>)

您可以通过将其转换为数组来解决它:

assertThat(result.getAnswers().toArray(), hasItemInArray(Matchers.hasProperty("content", equalTo("<h4>new comment</h4>"))));

Actuall it does not work for a little bit more complex Matcher, even using latest release.

assertThat(result.getAnswers(),
            Matchers.hasItem(Matchers.hasProperty("content")));

It will not work, you will get a:

The method assertThat(T, Matcher) in the type Assert is not applicable for the arguments (Set, Matcher>)

You can solve it by converting it to an array :

assertThat(result.getAnswers().toArray(), hasItemInArray(Matchers.hasProperty("content", equalTo("<h4>new comment</h4>"))));
浮云落日 2024-10-23 22:13:28

来自 http://code.google.com/p/hamcrest/source/browse/trunk/hamcrest-java/hamcrest-core/src/main/java/org/hamcrest/MatcherAssert.java签名是

assertThat(T actual, Matcher<? super T> matcher)

这样,问题是您的匹配器是 Matcher,而不是适用于超类或成就接口的任何实例的匹配器。

看起来 instanceOf 匹配器只是有一个有缺陷的类型绑定。
您可以通过执行类似的操作来解决该错误

@SuppressWarnings("unchecked")
Matcher/*no_param*/ isATestAchievement = instanceOf(TestAchievement.class);
assertThat(..., isATestAchievement);

From http://code.google.com/p/hamcrest/source/browse/trunk/hamcrest-java/hamcrest-core/src/main/java/org/hamcrest/MatcherAssert.java the signature is

assertThat(T actual, Matcher<? super T> matcher)

so the problem is that your matcher is a Matcher<TestAchievement>, not a matcher that works for any instance of a super-class or interface of achievement.

It looks like the instanceOf matcher just has a buggy type bound.
You can work around that bug by doing something like

@SuppressWarnings("unchecked")
Matcher/*no_param*/ isATestAchievement = instanceOf(TestAchievement.class);
assertThat(..., isATestAchievement);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文