好的,我认为这将是一个简短的问题。我有一个按日期排序的ArrayList,当然我看到它可以工作,但我也想为此编写一个测试。

我想检查列表中的下一个值(日期)是否比上一个低。我可以使用一些for并添加临时列表来做到这一点,但是我想知道是否有一个更简单的解决方案。我在hamrest文档中读到,有些像contains(包含hamrest)的对象会遍历对象(列表, map 等),但我仍然不知道下一步该怎么做。

最佳答案

[第一个选项] :您可以编写自己的Matcher。诸如此类(免责声明:这只是示例代码,未经测试,可能并不完美):

@Test
  public void theArrayIsInDescendingOrder() throws Exception
  {
    List<Integer> orderedList = new ArrayList<Integer>();
    orderedList.add(10);
    orderedList.add(5);
    orderedList.add(1);
    assertThat(orderedList, isInDescendingOrdering());
  }

  private Matcher<? super List<Integer>> isInDescendingOrdering()
  {
    return new TypeSafeMatcher<List<Integer>>()
    {
      @Override
      public void describeTo (Description description)
      {
        description.appendText("describe the error has you like more");
      }

      @Override
      protected boolean matchesSafely (List<Integer> item)
      {
        for(int i = 0 ; i < item.size() -1; i++) {
          if(item.get(i) <= item.get(i+1)) return false;
        }
        return true;
      }
    };
  }

这个示例是Integer的,但是您可以轻松地使用Date的。

[第二个选项] ,基于对OP问题中对contains的引用:您可以创建第二个列表,对原始列表进行排序,而不是使用assertThat(origin, contains(ordered))。这样,可以更精确地描述最终错误,因为如果某个元素不在预期的顺序中,则会指出该错误。例如,这段代码
@Test
  public void testName() throws Exception
  {
    List<Integer> actual = new ArrayList<Integer>();
    actual.add(1);
    actual.add(5);
    actual.add(3);
    List<Integer> expected = new ArrayList<Integer>(actual);
    Collections.sort(expected);
    assertThat(actual, contains(expected.toArray()));
  }

将生成描述
java.lang.AssertionError:
Expected: iterable containing [<1>, <3>, <5>]
     but: item 1: was <5>
    at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
    at org.junit.Assert.assertThat(Assert.java:865)
    at org.junit.Assert.assertThat(Assert.java:832)
    ...

10-07 16:19
查看更多