Hamcrest 中是否有匹配器来比较集合是否相等?有contains
,containsInAnyOrder
但我不需要equals
绑定到具体的集合类型。例如,我无法将 Arrays.asList 和 Map.values 与 Hamcrest 进行比较equals
。
提前致谢!
Hamcrest 中是否有匹配器来比较集合是否相等?有contains
,containsInAnyOrder
但我不需要equals
绑定到具体的集合类型。例如,我无法将 Arrays.asList 和 Map.values 与 Hamcrest 进行比较equals
。
提前致谢!
我无法将 Arrays.asList 和 Map.values 与 Hamcrest equals 进行比较。
这是因为 hamcrest 过分热心的类型签名。您可以进行这种相等比较,但您需要在编译之前将List
对象转换为。Collection
我经常不得不用 Hamcrest 进行铸造,这感觉不对,但有时这是让它编译的唯一方法。
强制转换为 Collection 可能有效,但它对底层的 Collection 实现做了一些假设(例如,订单?)。更通用的方法是编写自己的匹配器。
这是一个几乎完整的匹配器实现,可以满足您的需求(您需要填写导入和 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));
}
}
如果你对集合实现的 equals 方法有问题,你也可以先复制集合:
assertThat( new ArrayList<Whatever>(actual), equalTo( new ArrayList<Whatever>(expected) );
以下也可能有效:
assertThat(actual, both(everyItem(isIn(expected))).and(containsInAnyOrder(expected)));