假设我有一个List<A>
,其中
class A {
private Integer val;
private String name;
}
在我的测试用例中,我得到了这个列表,大小和内容都不确定。我想做的是将我知道必须在列表中的两个列表元素的val
字段与给定的name
字段进行比较;
List<A> list = logic.getList();
assertThat(list, allOf(hasItems(hasProperty("name", equalTo("first")),
hasItems(hasProperty("val", equalTo(***value from another member with name = "second"))));
我如何实现这一点,或者使用Hamcrest Matcher实现这一点甚至是可能的?
发布于 2019-06-27 01:28:52
您可以根据自己的需要实现自定义的Matcher
,例如检查一些具有名称的项是否具有相同的值字段:
final class FooTest {
static final class Foo {
final int val;
final String name;
// all args constructor
}
// custom matcher
static final class FoosHasSameValues extends TypeSafeMatcher<List<Foo>> {
private final Set<String> names;
// all args constructor
FoosHasSameValues(final String... names) {
this(new HashSet<>(Arrays.asList(names)));
}
@Override
protected boolean matchesSafely(final List<Foo> items) {
final List<Integer> values = items.stream()
// filter only items with specified names
.filter(i -> this.names.contains(i.name))
// select only values
.map(i -> i.val)
.collect(Collectors.toList());
if (values.size() != this.names.size()) {
// matching failed if list doesn't contains all
// needed items with names
return false;
}
// check https://stackoverflow.com/a/29288616/1723695
return values.stream().distinct().limit(2).count() <= 1;
}
@Override
public void describeTo(final Description description) {
description.appendText("has items [")
.appendValue(String.join(", ", this.names))
.appendText("] with same values");
}
}
@Test
void testMatchers() throws Exception {
MatcherAssert.assertThat(
Arrays.asList(
new Foo("first", 1),
new Foo("second", 1),
new Foo("third", 2)
),
new FoosHasSameValues("first", "second")
);
}
}
发布于 2016-06-07 19:27:21
编写自定义匹配器可以清理您的测试逻辑:
public class AMatcher extends TypeSafeMatcher<A> {
A actual;
public AMatcher(A actual) { this.actual = actual; }
protected boolean matchesSafely(A a) {
return a.equals(actual); // or compare individual fields...
}
public void describeTo(Description d) {
d.appendText("should match "+actual); // printed out when a match isn't found.
}
}
然后,使用它:
assertThat(list, allOf(new AMatcher(a1), new AMatcher(a2)));
或者,如果你不想创建A的实例来创建匹配器,可以创建一个接受'name‘和'val’参数的AMatcher构造函数。
https://stackoverflow.com/questions/37625209
复制相似问题