如何检查Object集合是否包含给定顺序的Object属性

时间:2017-01-02 12:49:45

标签: java junit4

让我们说我有一本书籍集。(这本书来自弹性搜索)

class Book {

String name;
String author;

// 10 other properties

}

现在在我的JUnit中,我需要测试这些图书是否按照name的升序排列(我最近需要对所有其他11个属性进行测试)

是否可以在我的JUnit测试类中测试book的顺序而不创建Book对象?如果是的话怎么样?

3 个答案:

答案 0 :(得分:1)

这不是特定于JUnit的,但可能this answer在这有帮助:

它建议这种通用方法:

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;
}

答案 1 :(得分:1)

看看AssertJ库进行测试,它可以确定是否有例如列表

首先从书籍中提取姓名:

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

随后使用AssertJ方法测试顺序如下:

Assertions.assertThat(names).isSorted()

当然,您也可以提供自己的比较器并使用isSortedAccordingTo方法

供参考 http://joel-costigliola.github.io/assertj/core/api/org/assertj/core/api/ArraySortedAssert.html

注意:我没有尝试编译代码

答案 2 :(得分:0)

我认为基本上有两个选项:你可以使用一个库来使(某些)测试的编写更方便,你可以依赖普通JUnit并“手动”完成其他任务。

对于图书馆选项,这不是我的专长,但我知道有一些可供选择。 pezetem在another answer中写的关于AssertJ的内容听起来很有希望,特别是isSortedAccordingTo()。但是,它确实要求您为要检查的每个排序编写Comparator。在做出明智的选择之前,我会仔细研究不同的图书馆,并着眼于其他测试。

如果您现在不想依赖图书馆,我建议您自己写一个这样的辅助方法:

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;
}

您将识别来自this answer的逻辑,但我已将方法签名扭曲以符合您的需要。现在您的测试非常简单:

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

但有两点注意事项:

  1. 我假设您的Book课程有吸气剂,并且您有理由想要添加它们,而不仅仅是单元测试。如果没有,您可以使用isSortedBy(b -> b.name, listOfBooks)
  2. 当你说收藏时,我认为你的意思是清单。其他集合类型(如集合)可能没有订单,因此检查它们是否已排序可能没有意义。
  3. 如果您希望您的方法更通用,您可以添加另一个类型参数以允许除书籍以外的其他内容列表:

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

    就我而言,我会等到我看到需要的时候。

    在编写单元测试时,我发现值得考虑如何向测试人员报告测试失败,如果测试失败,他/她将需要什么信息。只知道列表没有根据属性排序,它应该排序可能没那么有用。除非列表很长,否则我认为你可能只是将整个列表转储为消息:

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

    (您需要确保您的Book类具有toString方法才能使其有用。)如果您有辅助方法返回,当然有办法进行更精细的故障报告特定消息,而不仅仅是truefalse