Java Hamcrest:集合包含类型的项目
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4981586/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java Hamcrest : Collection contains item of type
提问by Marty Pitt
I'd like to assert that List<Achievement>
contains a member of type TestAchievement
.
我想断言它List<Achievement>
包含一个 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>>)
类型 Assert 中的方法 assertThat(T, Matcher) 不适用于参数 (List, Matcher<Iterable<TestAchievement>>)
What's the correct syntax for this type of assertion using Hamcrest?
使用 Hamcrest 进行此类断言的正确语法是什么?
采纳答案by Marty Pitt
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.
这里的帖子表明这是 Hamcrest 的一个缺陷,所以我前往 hacmrest 站点注册一个错误,当时我发现我使用的 mvn / ivy 依赖声明已经过时,给了我一个旧版本的哈姆克雷斯特。
This bug exists with 1.1, which is the latest if declared using
此错误存在于 1.1 中,如果使用声明,这是最新的
<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)));
回答by Mike Rylander
There is a bugin Java 6 that relates to this.
Java 6 中有一个与此相关的错误。
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:
有趣的是,如果您使用instanceOf()
而不是isA()
您再次遇到问题。(尽管如果您忽略警告,这可能对您有用。)扩展上一个修复程序,您可以使用:
Matcher<TestAchievement> itemMatcher = Matchers.instanceOf(TestAchievement.class);
Matcher<Iterable<? super TestAchievement>> matcher = hasItem(itemMatcher);
assertThat(achievements, matcher);
回答by NamshubWriter
assertThat(achievements, hasItem(
IsInstanceOf.<Achievement>instanceOf(TestAchievement.class)));
回答by joerx
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.
它确实有所作为。现在我的测试完美无缺。一行复制到数组似乎是一种合理的权衡,可以省去很多麻烦。
回答by Ark Xu
Actuall it does not work for a little bit more complex Matcher, even using latest release.
实际上,即使使用最新版本,它也不适用于更复杂的 Matcher。
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>)
类型 Assert 中的方法 assertThat(T, Matcher) 不适用于参数 (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>"))));
回答by limc
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>
.
我一直在讨论这个问题,似乎我所知道的唯一方法是转换List<Achievement>
为List<Object>
. 问题是CoreMatchers.instanceOf()
返回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)));
回答by Mike Samuel
From http://code.google.com/p/hamcrest/source/browse/trunk/hamcrest-java/hamcrest-core/src/main/java/org/hamcrest/MatcherAssert.javathe 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.
所以问题是你的匹配器是一个Matcher<TestAchievement>
,而不是一个适用于超类或成就接口的任何实例的匹配器。
It looks like the instanceOf
matcher just has a buggy type bound.
You can work around that bug by doing something like
看起来instanceOf
匹配器只是有一个错误的类型绑定。您可以通过执行以下操作来解决该错误
@SuppressWarnings("unchecked")
Matcher/*no_param*/ isATestAchievement = instanceOf(TestAchievement.class);
assertThat(..., isATestAchievement);