AssertThat - hamcrest - проверить, отсортирован ли список

Хорошо, я думаю, что это будет короткий вопрос. У меня есть ArrayList, который я отсортировал по дате, конечно, я вижу, что это работает, но я также хотел бы написать тест для него.

Я хочу проверить, находится ли следующее значение (дата) в моем списке ниже предыдущего. Я могу сделать это с помощью некоторого for и добавления списка temp, но мне интересно, есть ли более простое решение. Я прочитал в документации hamrest, что есть что-то вроде contains (hamrest содержит), который перебирает объект (список, карту и т.д.), Но все же я понятия не имею, что делать дальше.

Ответы

Ответ 1

[Первый вариант]: вы можете написать свой собственный 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.

[Второй вариант], на основе ссылки на contains в вопросе OP: вы можете создать второй список, заказывая исходный, чем использовать 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)
    ...

Ответ 2

Там открытый запрос для такого совпадения, но, к сожалению, он еще не реализован.

Я бы пошел на что-то намного проще - скопировал список, отсортировал его и сравнил с оригиналом:

@Test
public void testListOrder() {
    ArrayList<SomeObject> original = ...;
    ArrayList<SomeObject> sorted = new ArrayList<SomeObject>(original);
    Collections.sort(sorted);
    Assert.assertEquals ("List is not sorted", sorted, original);
}

Ответ 4

Для небольших коллекций я предлагаю обеспечить ожидаемый сбор, закодированный в коде. Это unit test и не должно содержать никакой логики. После этого вы можете сравнить две коллекции. (используйте hamcrest для проверки эквивалента)

Ответ 5

У меня была аналогичная проблема, я просто проверяю, больше ли значение следующей даты в миллисекундах, чем предыдущее в этом списке.

/**
 * Test sort by date
 */
@Test
public void findAllMessagesSortByDate() {
    Collection<Message> messages = messageService.getAllMessagesSortedByDate();
    long previousTime = messages.iterator().next().getDate().getTimeInMillis();
    for (Message message : messages) {
        assertTrue(message.getDate.getTimeInMillis() <= previousTime);
        previousTime = message.getMessageFolderTs().getTimeInMillis();
    }
}

Ответ 6

Вы можете проверить мой ответ в другой теме, но подход остается таким же - вы должны проверить, находятся ли элементы в ожидаемом порядке.

Как проверить, содержит ли коллекция элементы в указанном порядке с помощью Hamcrest

Этот подход предполагает использование библиотеки "Hamcrest".

Надеюсь, что это поможет.