JUnit:有没有办法一次断言所有数组值?

JUnit: Is there a way to assert all array values at once?

我有一张地图,其中的值是一个简单的 pojo。 例如(在一个非常松散的代码中):

Class Data{
  int a;
  Boolean b;
}

Map<Integer, Data> myMap = new HashMap<>();

现在正在用值填充地图。 然后最后我想断言所有映射条目的数据对象的所有 b 值都是,例如,true。

所以我尝试了类似的方法:

private void computeAllBooleans(){

    allBooleansStatus = true;
    myMap.values()
        .forEach(data ->
            allBooleansStatus = allBooleansStatus && data.getB();
}
  1. 有没有更简洁的方法来实现?
  2. 有没有办法用 JUnit(或其他相关框架,如 hamcrest、assertj 等)进行断言?

(我注意到这个 link 但不明白如何使用那里的建议答案...)

您可以使用 allMatch 终端操作来检查地图的所有元素,如下所示:

myMap.values().stream().allMatch(Data::getB);

或者使用过滤器并像这样计算:

myMap.values().stream().filter(Data::getB).count() == myMap.size();

您可以使用 assertj 库使用更优雅的方式,使用 allMatchallSatisfy

https://assertj.github.io/doc/#assertj-core-group-satisfy

List<TolkienCharacter> hobbits = list(frodo, sam, pippin);

// all elements must satisfy the given assertions
assertThat(hobbits).allSatisfy(character -> {
  assertThat(character.getRace()).isEqualTo(HOBBIT);
  assertThat(character.getName()).isNotEqualTo("Sauron");
});

AssertJ Core you can chain extracting and containsOnly:

Map<Integer, Data> myMap = new HashMap<>();
myMap.put(1, new Data(1, true));
myMap.put(2, new Data(2, true));
myMap.put(3, new Data(3, true));

assertThat(myMap.values()).extracting(Data::getB).containsOnly(true);

使用 AssertJ 的好处还包括在出现故障时提供格式良好的错误消息。例如,以下内容:

Map<Integer, Data> myMap = new HashMap<>();
myMap.put(1, new Data(1, true));
myMap.put(2, new Data(2, false));
myMap.put(3, new Data(3, false));

assertThat(myMap.values()).extracting(Data::getB).containsOnly(true);

会失败:

java.lang.AssertionError: 
Expecting ArrayList:
  [true, false, false]
to contain only:
  [true]
but the following element(s) were unexpected:
  [false, false]

更多 Iterable 断言在 official documentation 中描述。