【问题标题】:testing the order of a collection测试集合的顺序
【发布时间】:2015-08-16 15:03:18
【问题描述】:

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

例如,我想验证它们是否按顺序排列

id 1, 
id 2,
id 3,

或者其他情况

date mostRecent
date older
date oldest

或者在另一种情况下

enum ValueA
enum ValueB
enum ValueC

基本上我想测试我指定的排序是否正确通过,但对象上只有一个属性实际上会影响这一点,所以我想用hasFirstItem( withPropertyEqualTo ... has secondItem( withPropertyEqualTo的一些变体指定我的测试

我知道我会写

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

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

【问题讨论】:

  • 你可以使用 Java 8 吗?如果是这样,我可能会将属性函数映射到列表上并断言结果。
  • JUnit/Hamcrests assertThat(actual, contains(item1, item2, ...)); 应该这样做。你甚至可以编写自己的匹配器来做你想要的检查

标签: java unit-testing junit junit4 hamcrest


【解决方案1】:

你应该可以像这样使用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 的方法,因为它旨在测试 JavaBean。

【讨论】:

  • 不是contains 无序吗?这意味着如果new Foo("b") 是第一个对象,它仍然会通过?
  • 不,containsInAnyOrder 检查无序明智。 contains 将检查 item1 与 item1 等等
  • 命名...谢谢,我错误地假设包含,在功能上类似于 Collection.contains。
  • @xenoterracide 同意,拥有containsInOrdercontains(以任何顺序)IMO 会更有意义且不会令人困惑
【解决方案2】:

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

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);

【讨论】:

  • 您不应该使用assertNotEquals 而不是assertEquals 来通过测试吗?
  • @ChetanKinger 我理解 OP 的方式,他有“生产”代码,它以某种属性排序的方式生成列表。如果按该属性显式排序列表并没有改变它,我们可以推断它已经排序,正如预期的那样 - 因此使用assertEquals
  • assertEquals 在这种情况下是有意义的。话虽如此,我无法在 OP 中找到足够的内容来支持您的解释。
【解决方案3】:

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

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));
 }
}

【讨论】:

  • 也许你的意思是list.get(i) &gt; list.get(i+1)
【解决方案4】:

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

Object previous = list.get(0);

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

【讨论】:

    【解决方案5】:

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

    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));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-04
      • 2019-06-05
      • 2015-11-24
      • 2020-02-22
      • 1970-01-01
      相关资源
      最近更新 更多