Hamcrest中有没有匹配器来比较集合的等价性?有contains和containsInAnyOrder,但我需要不绑定到具体集合类型的equals。例如,我不能将Arrays.asList和Map.values与Hamcrest equals进行比较。
提前感谢!
发布于 2009-12-25 19:32:41
I不能将Arrays.asList和Map.values与Hamcrest相等进行比较。
这是因为hamcrest过于热心的类型签名。您可以进行这种相等比较,但是需要将List对象强制转换为Collection,然后才能进行编译。
我经常不得不使用Hamcrest进行造型,这感觉是错误的,但有时这是编译它的唯一方法。
发布于 2010-01-08 21:41:05
强制转换为Collection可能会起作用,但它会对底层的Collection实现进行一些假设(例如,order?)。一种更通用的方法是编写自己的匹配器。
下面是一个几乎完整的匹配器实现,它完成了您想要做的事情(您需要填写imports和describeTo方法)。请注意,此实现要求两个集合的所有元素相等,但顺序不一定相同。
public class IsCollectionOf<T> extends TypeSafeMatcher<Collection<T>> {
private final Collection<T> expected;
public IsCollectionOf(Collection<T> expected) {
this.expected = expected;
}
public boolean matchesSafely(Collection<T> given) {
List<T> tmp = new ArrayList<T>(expected);
for (T t : given) {
if (!tmp.remove(t)) {
return false;
}
return tmp.isEmpty();
}
// describeTo here
public static <T> Matcher<Collection<T>> ofItems(T... items) {
return new IsCollectionOf<T>(Arrays.asList(items));
}
}发布于 2012-08-27 23:54:14
如果您在使用集合实现的equals方法时遇到问题,也可以先复制集合:
assertThat( new ArrayList<Whatever>(actual), equalTo( new ArrayList<Whatever>(expected) );此外,以下方法也可能会起作用:
assertThat(actual, both(everyItem(isIn(expected))).and(containsInAnyOrder(expected)));https://stackoverflow.com/questions/1960971
复制相似问题