测试集合的顺序

testing the order of a collection

给定一个对象列表,我想测试它们 return 的顺序是否正确,但我不想断言整个对象。

例如,我想验证它们是否符合

id 1, 
id 2,
id 3,

或另一种情况

date mostRecent
date older
date oldest

或者在另一种情况下

enum ValueA
enum ValueB
enum ValueC

基本上我想测试我指定的排序是否正确通过但对象上只有一个 属性 实际上会影响这个,所以我想用 [=14 的一些变体指定我的测试=]

我知道我会写

 assertEquals( property, list.get(0).id )
 assertEquals( property, list.get(1).id )

但我宁愿做一些让失败更明显的事情,因为它是一个排序问题,也许是声明性的,一次测试整个集合。这可能吗?

解决此问题的一种方法是根据给定的 属性 简单地对列表进行排序,然后将排序后的列表与原始列表进行比较:

public class MyObjectIdComparator implements Comparator<MyObject> {

    @Override
    public int compare (MyObject a, MyObject b) {
        return a.getId().compareTo(b.getId());
    }
}

ArrayList<MyObject> orig = getListFromSomewhere();
ArrayList<MyObject> sorted = new ArrayList<>(orig);
Collections.sort (sorted, new MyObjectIdComparator());

assertEquals ("orig list is in the wrong order, sorted, orig);

您可以在断言命令中指定消息,

assertEquals("Sort out of order at index " + i, expected.get(i), list.get(i));

或者,

assertSame("Sort out of order at index " + i, expected.get(i), list.get(i));

您能否遍历集合并报告感兴趣的 属性 失败的第一个案例?

for (int i=0; i<list.size()-1; ++i) {
 if (list.get(i) > list.get(i+1)) {
    fail(String.format("%s > %s; in the wrong place in the sorted list for index %d",
        list.get(i), list.get(i+1), i));
 }
}

假设 属性 对象实现 Comparable 接口:

Object previous = list.get(0);

for (Object element : list) {
    assertTrue(previous.getProperty().compareTo(element.getProperty()) <= 0);
    previous = element;
}

您应该可以像这样使用 hamcrest 的匹配器 hasProperty

public class Foo {

    private String a;

    public Foo(String a) {
        this.a = a;
    }

    public Object getStr() {
        return a;
    }


    public static void main(String[] args) {
        List<Foo> l = Arrays.asList(new Foo("a"), new Foo("b"));
        Assert.assertThat(l, contains(hasProperty("str", equalTo("a")),
                                      hasProperty("str", equalTo("b"))));
    }

}

其中 "str" 是您要检查的 属性 的名称。请注意,这仅适用于名为 getXxx 的方法,因为它旨在测试 JavaBeans。