首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何将复杂对象列表的成员与Hamcrest进行比较?

如何将复杂对象列表的成员与Hamcrest进行比较?
EN

Stack Overflow用户
提问于 2016-06-04 08:31:07
回答 2查看 1.6K关注 0票数 3

假设我有一个List<A>,其中

代码语言:javascript
复制
class A {
    private Integer val;
    private String name;
}

在我的测试用例中,我得到了这个列表,大小和内容都不确定。我想做的是将我知道必须在列表中的两个列表元素的val字段与给定的name字段进行比较;

代码语言:javascript
复制
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实现这一点甚至是可能的?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-06-27 01:28:52

您可以根据自己的需要实现自定义的Matcher,例如检查一些具有名称的项是否具有相同的值字段:

代码语言:javascript
复制
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")
        );
    }
}
票数 1
EN

Stack Overflow用户

发布于 2016-06-07 19:27:21

编写自定义匹配器可以清理您的测试逻辑:

代码语言:javascript
复制
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.
   }
}

然后,使用它:

代码语言:javascript
复制
assertThat(list, allOf(new AMatcher(a1), new AMatcher(a2)));

或者,如果你不想创建A的实例来创建匹配器,可以创建一个接受'name‘和'val’参数的AMatcher构造函数。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37625209

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档