使用Hamcrest匹配器在对象列表中查找属性

3

我有一个Java POJO。

public class Emp {    
    private String name;
    private int id;
}

我有一个员工列表(目标):

 List<Emp> target = new ArrayList<Emap>();
 // Add emp object in list
 assertThat(target, containsInAnyOrder(????));

containsInAnyOrder 中,我必须使用类似于 hasProperty("name" , is(equalTo("John")) 的语法。我需要检查列表中特定属性的特定值,那么应该怎么写呢?我没有找到任何关于带有对象列表的 "containsInAnyOrder" 的例子。


问题是什么? - shmosel
好的,你有一些更新;但也许你会发现其他答案更有帮助。无论如何,到目前为止你已经得到了很多信息...应该足够让你开始了。 - GhostCat
2个回答

1
我知道你想要一个“通用”的东西,比如:遍历整个列表;然后通过名称检索对象的一个字段;然后检查其中是否有匹配的元素。我认为 Hamcrest 中没有这样的东西:因为这对于预定义的匹配器来说太过复杂了。因此,唯一符合这个要求的“答案”就是创建自己的客户匹配器,使用反射来实际执行它。更多细节:你可以从我的一个旧的答案开始,其中包含一个可直接使用的适用于列表的匹配器。实际上,现在只剩下一个事情要做:将我的列表匹配器更改为执行不同类型的检查。在那里,你可以利用其他答案中列出的 Apache Commons EqualsBuilder。在实现这个过程中应该没有什么大的障碍,只需要“工作”即可。
但是:我不确定这是否真的是正确的方法。正如所说的一样,你试图解决的问题对我来说听起来非常具体;而且你知道:任何使用反射的单元测试都存在与“基于反射”的代码相同的问题——当有人更改你的生产代码时,编译器不会告诉你;例如通过更改name字段的名称。

因此:与其使用反射,我宁愿在“生产代码”方面做出妥协;例如添加一个简单的getter:
public class Emp {
... fields
  String getName() { return name; }

而不是使用反射来比较通用属性,您编写一个匹配器,该匹配器知道使用该getter获取名称并进行比较。

是的,请。我以为它应该存在的。帮帮我。 - rishi

1
如果您要比较的对象始终像Java Pojo一样简单,那么您可以查看Apache Commons Lang3中的EqualsBuilder。特别是这个方法:
public static boolean reflectionEquals(Object lhs, Object rhs, boolean testTransients)

你可以实现自己的“equals”匹配器,将比较委托给reflectionEquals。为此,您需要从Hamcrest中的TypeSafeDiagnosingMatcher<T>类派生子类。
class ReflectiveEqualsMatcher<T> extends TypeSafeDiagnosingMatcher<T> {

    private final T other;

    public ReflectiveEqualsMatcher(T divisor) {
        this.other = divisor;
    }

    @Override
    protected boolean matchesSafely(T me, Description description) {
        return EqualsBuilder.reflectionEquals(me, other, true);
    }

    @Override
    public void describeTo(Description description) {
    }

    public static <T> ReflectiveEqualsMatcher<T> same(T other) {
        return new ReflectiveEqualsMatcher(other);
    }
}

使用它:

//static import ReflectiveEqualsMatcher.same first
assertThat(target, containsInAnyOrder(same(obj1), same(obj2), same(obj3)));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接