2

Lets say that I have a Collection of Books.(the book are fetched from Elastic Search)

class Book {

String name;
String author;

// 10 other properties

}

Now In my JUnit I need to test whether the Books are in the Ascending order of name (latest I need to test the same with all the other 11 properties)

Is it possible to test the order of book without creating Book object in my JUnit test class? if yes how?

Jobin
  • 5,610
  • 5
  • 38
  • 53

3 Answers3

1

This is not JUnit specific but maybe this answer in this so helps:

It suggests this generic method:

public static <T extends Comparable<? super T>> boolean isSorted(final Iterable<T> iterable) {
    Iterator<T> iter = iterable.iterator();
    if (!iter.hasNext()) {
        return true;
    }
    T t = iter.next();
    while (iter.hasNext()) {
        T t2 = iter.next();
        if (t.compareTo(t2) > 0) {
            return false;
        }
        t = t2;
    }
    return true;
}
Community
  • 1
  • 1
kism3t
  • 1,343
  • 1
  • 14
  • 33
1

take a look at AssertJ library for testing, it has with it you can determine if the for example list is ordered

first extract names from books:

List<String> names = books.stream()
                          .map(book -> book.getName())
                          .collect(Collectors.toList());

subsequently use AssertJ method to test the order like:

Assertions.assertThat(names).isSorted()

of course you can also provide your own comparators and use isSortedAccordingTo method

for the reference http://joel-costigliola.github.io/assertj/core/api/org/assertj/core/api/ArraySortedAssert.html

note: i did not try to compile the code

pezetem
  • 2,503
  • 2
  • 20
  • 38
0

There are basically two options as I see it: You can use a library that will make writing of (some) tests more convenient, and you can rely on plain JUnit and do everything else “by hand”.

For the library option, this is not my expertise, but I do know that there are a number to choose from. What pezetem writes in another answer about AssertJ sounds promising, particularly isSortedAccordingTo(). It does require you to write a Comparator for each of the sortings you want to check, though. I’d take a good look at the different libraries also with an eye to other tests than this one before making an informed choice.

If you prefer not to depend on a library for the purpose right now, I suggest you write yourself an auxiliary method like this:

private static <T extends Comparable<? super T>> boolean isSortedBy(Function<Book, T> getMethod, List<Book> list) {
    if (list.isEmpty()) {
        return true;
    }
    Iterator<Book> bit = list.iterator();
    T attr = getMethod.apply(bit.next());
    while (bit.hasNext()) {
        T nextAttr = getMethod.apply(bit.next());
        if (nextAttr.compareTo(attr) < 0) {
            return false;
        }
        attr = nextAttr;
    }
    return true;
}

You will recognize the logic from this answer, but I have twisted the method signature to match your need here. Now your test is as simple as:

    assertTrue(isSortedBy(Book::getName, listOfBooks));

Two notes though:

  1. I am assuming that your Book class has getters, and there are reasons why you may want to add them, not only for the unit test. If not, you may use isSortedBy(b -> b.name, listOfBooks).
  2. When you said collection, I assume you meant list. Other collection types (like sets) may not have an order, so it may not be meaningful to check whether they are sorted.

If you want your method more general, you may add another type parameter to allow lists of other things than books:

private static <E, T extends Comparable<? super T>> boolean isSortedBy(Function<E, T> getMethod, List<E> list)

For my part I would wait until I see a need though.

When writing unit tests I find it worth thinking about how test failures are reported to the tester, what information s/he will need if a test fails. Only knowing the the list wasn’t sorted accoring to the attribute it should be sorted by may not be that useful. Unless you list is long, I think that you may just dump the entire list as message:

    assertTrue(listOfBooks.toString(), isSortedBy(Book::getName, listOfBooks));

(You will want to make sure your Book class has a toString method for this to be useful.) There are of course ways to do more refined failure reporting if you have the auxiliary method return a specific message rather than just true or false.

Community
  • 1
  • 1
Ole V.V.
  • 81,772
  • 15
  • 137
  • 161