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);
}
Ответ 3
Также можно проверить его с помощью GUAVA:
import com.google.common.collect.Ordering;
...
assertTrue(Ordering.natural().isOrdered(list));
Дополнительная информация здесь: Как определить, отсортирован ли список в Java?
Ответ 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".
Надеюсь, что это поможет.