List<String> expectedStrings = Arrays.asList("link1", "link2");
List<String> strings = Arrays.asList("lalala link1 lalalla", "lalalal link2 lalalla");
对于每个期望的字符串,我需要断言“strings”中的任何一个字符串都包含期望的字符串。我该如何使用Hamcrest进行断言?感谢您的关注。
在查看这个旧答案后,我发现您可以使用更好的内置匹配器组合,从而使断言和错误消息更易读:
expectedStrings.forEach(expectedString ->
assertThat(strings, hasItem(containsString(expectedString))));
您可以使用流轻松完成它:
assertThat(expectedStrings.stream().allMatch(
expectedString -> strings.stream()
.anyMatch(string -> string.contains(expectedString))),
is(true));
< p > allMatch
会确保检查所有的 expectedStrings
,而使用 strings
上的 anyMatch
,您可以有效地检查任何字符串是否包含期望的字符串。
目前,尽管您可以组合多个匹配器,但 Hamcrest 中还没有满足此要求的匹配器。
因此,在像您这样的情况下,我认为最好的解决方案是创建自己的匹配器。为什么?
所以在您的情况下,您需要匹配第一个列表中包含第二个列表中任何字符串,您可以创建一个类似下面的 Matcher:
public class ContainsStringsOf extends BaseMatcher<List<String>> {
private final List<String> valuesToCompare;
public ContainsStringsOf(List<String> valuesToCompare) {
this.valuesToCompare = valuesToCompare;
}
@Override
public void describeTo(Description description) {
description.appendText("doesn't contains all of " + valuesToCompare.toString() + " text");
}
@Override
public boolean matches(Object o) {
List<String> values = (List<String>) o;
for (String valueToCompare : valuesToCompare) {
boolean containsText = false;
for (String value : values) {
if (value.contains(valueToCompare)) {
containsText = true;
}
}
if (!containsText) {
return false;
}
}
return true;
//note: you can replace this impl with java-8 @florian answer comparison
//return valuesToCompare.stream().allMatch(exp -> strings.stream().anyMatch(st-> st.contains(exp)))
}
@Factory
public static Matcher<List<String>> containsStringsOf(List<String> collection) {
return new ContainsStringsOf(collection);
}
}
然后您可以像使用Hamcrest Matcher一样使用它:
List<String> expectedStrings = Arrays.asList("link1", "link2");
List<String> strings = Arrays.asList("lalala link1 lalalla", "lalalal link2 lalalla");
Assert.assertThat(strings , containsStringsOf(expectedStrings));
我喜欢自定义匹配器的想法。你可以将流机制用作其核心。这里是一个简单(低效)的例子:
assertThat( infoLogs.stream().filter(logItem -> logItem.contains("writing out group")).collect(Collectors.toList()).size()).isNotZero();