2013-11-06 3 views
14

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

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

+0

Обеспечить некоторый код братан :) вы можете получить помощь быстро –

+2

я не предоставлять какой-либо код, потому что я думал, что я не должен, так как мой вопрос о какой-либо список (коллекция), что содержит элемент, и я хочу сравнить элемент из списка со следующим в том же списке. – ojciecmatki

ответ

13

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

[Второй вариант], на основании ссылки на 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) 
    ... 
+0

спасибо, второй вариант, что я искал – ojciecmatki

+0

@ ŁukaszRyś, рад помочь. Пожалуйста, отметьте ответ, как принято тогда :) – ThanksForAllTheFish

+0

второй вариант работает, поэтому сначала переборщик/слишком специализированный –

13

Есть open request for such a matcher, но, к сожалению, он еще не реализован.

я бы пойти на что-то гораздо проще - скопировать список, сортировать его и сравнить с оригиналом:

@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); 
} 
+0

Да, вы правы, его довольно симплейное решение, мне было только интересно, есть ли способ сравнить только элементы из одного списка (например, у меня есть 20.01.1991 и 20.02.1991 в моем списке и сравнить их обоих) – ojciecmatki

3

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

2

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

/** 
* 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(); 
    } 
} 
0

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

How to check if collection contains items in given order using Hamcrest

Этот подход предполагает библиотека 'Hamcrest', которые будут использоваться.

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

6

Также можно проверить его с помощью гуавы:

import com.google.common.collect.Ordering; 

...

assertTrue(Ordering.natural().isOrdered(list)); 

Более подробная информация здесь: How to determine if a List is sorted in Java?

Смежные вопросы