如何检查对象集合是否包含给定顺序的对象属性
How to check if an Object collection contains an Object properties in given order
假设我有一本书集。(这本书是从 Elastic Search 中获取的)
class Book {
String name;
String author;
// 10 other properties
}
现在在我的 JUnit 中,我需要测试书籍是否按 name
的升序排列(最近我需要对所有其他 11 个属性进行相同的测试)
在我的 JUnit 测试 class 中是否可以在不创建 Book
对象的情况下测试 book
的顺序?如果是怎么办?
这不是特定于 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;
}
查看用于测试的 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
注意:我没有尝试编译代码
我认为基本上有两种选择:您可以使用一个库来使(某些)测试的编写更加方便,并且您可以依靠简单的 JUnit
并“手动”完成其他所有操作”.
对于图书馆选项,这不是我的专长,但我知道有很多选择。 pezetem 在 中写的关于 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;
}
您会认出 中的逻辑,但我在这里扭曲了方法签名以满足您的需要。现在您的测试很简单:
assertTrue(isSortedBy(Book::getName, listOfBooks));
不过有两个注意事项:
- 我假设你的
Book
class 有吸气剂,你可能想要添加它们是有原因的,不仅仅是为了单元测试。如果没有,您可以使用 isSortedBy(b -> b.name, listOfBooks)
.
- 当您说集合时,我假设您指的是列表。其他集合类型(如集合)可能没有顺序,因此检查它们是否已排序可能没有意义。
如果您希望您的方法更通用,您可以添加另一个类型参数以允许列出书籍以外的其他内容:
private static <E, T extends Comparable<? super T>> boolean isSortedBy(Function<E, T> getMethod, List<E> list)
就我而言,我会等到我看到需要为止。
在编写单元测试时,我发现值得考虑如何向测试人员报告测试失败,如果测试失败,s/he 需要什么信息。只知道列表没有按照它应该排序的属性排序可能没有那么有用。除非你的列表很长,否则我认为你可以将整个列表转储为消息:
assertTrue(listOfBooks.toString(), isSortedBy(Book::getName, listOfBooks));
(您需要确保您的 Book
class 有一个 toString
方法才能发挥作用。)当然有一些方法可以进行更精细的故障报告,如果你有辅助方法 return 一个特定的消息而不仅仅是 true
或 false
.
假设我有一本书集。(这本书是从 Elastic Search 中获取的)
class Book {
String name;
String author;
// 10 other properties
}
现在在我的 JUnit 中,我需要测试书籍是否按 name
的升序排列(最近我需要对所有其他 11 个属性进行相同的测试)
在我的 JUnit 测试 class 中是否可以在不创建 Book
对象的情况下测试 book
的顺序?如果是怎么办?
这不是特定于 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;
}
查看用于测试的 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
注意:我没有尝试编译代码
我认为基本上有两种选择:您可以使用一个库来使(某些)测试的编写更加方便,并且您可以依靠简单的 JUnit
并“手动”完成其他所有操作”.
对于图书馆选项,这不是我的专长,但我知道有很多选择。 pezetem 在 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;
}
您会认出
assertTrue(isSortedBy(Book::getName, listOfBooks));
不过有两个注意事项:
- 我假设你的
Book
class 有吸气剂,你可能想要添加它们是有原因的,不仅仅是为了单元测试。如果没有,您可以使用isSortedBy(b -> b.name, listOfBooks)
. - 当您说集合时,我假设您指的是列表。其他集合类型(如集合)可能没有顺序,因此检查它们是否已排序可能没有意义。
如果您希望您的方法更通用,您可以添加另一个类型参数以允许列出书籍以外的其他内容:
private static <E, T extends Comparable<? super T>> boolean isSortedBy(Function<E, T> getMethod, List<E> list)
就我而言,我会等到我看到需要为止。
在编写单元测试时,我发现值得考虑如何向测试人员报告测试失败,如果测试失败,s/he 需要什么信息。只知道列表没有按照它应该排序的属性排序可能没有那么有用。除非你的列表很长,否则我认为你可以将整个列表转储为消息:
assertTrue(listOfBooks.toString(), isSortedBy(Book::getName, listOfBooks));
(您需要确保您的 Book
class 有一个 toString
方法才能发挥作用。)当然有一些方法可以进行更精细的故障报告,如果你有辅助方法 return 一个特定的消息而不仅仅是 true
或 false
.