我可以以某种方式使用AssertJ断言List只有一个(子)类的实例吗?
public class A {}
public class B extends A {}
public class C extends A {}
@Test
public void test() {
List<A> list = new ArrayList<A>();
list.add(new B());
Assertions.assertThat(list).containsOnlyOnce(B.class);
}
答案 0 :(得分:7)
我会按原样使用AssertJ extracting feature:
assertThat(list).extracting("class")
.containsOnlyOnce(B.class);
答案 1 :(得分:3)
有一个方法hasOnlyElementsOfType(Class),它验证Iterable中的所有元素都具有指定的类型(包括给定类型的子类)。
解决方案可能如下:
assertThat(list).hasOnlyElementsOfType(B.class).hasSize(1);
答案 2 :(得分:2)
您的代码存在问题,list
的类型为A
,
但您尝试使用containsOnlyOnce
验证的元素类型为Class<B>
。
您需要使用相应的类型。 例如,您可以在列表中提取类:
Stream<Class<?>> classes = list.stream().map(x -> x.getClass());
Assertions.assertThat(classes).containsOnlyOnce(B.class);
答案 3 :(得分:2)
您需要定义Condition。
以下将断言list
仅包含类型为B.class
的单个对象引用。
Condition condition = new Condition() {
@Override
public boolean matches(Object o) {
return o.getClass() == B.class;
}};
Assertions.assertThat(list).areExactly(1, condition);
以下情况将失败:
list.add(new B());
list.add(new B());
以及
B b = new B();
list.add(b);
list.add(b);
使用Java 8 Stream API可以像
一样实现long countOfClassB = list.stream().filter(t -> t instanceof B).count();
Assertions.assertThat(countOfClassB).isEqualTo(1L);