10

我可以以某种方式使用 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);
}
4

4 回答 4

16

有一个方法hasOnlyElementsOfType(Class),它验证 Iterable 中的所有元素都具有指定的类型(包括给定类型的子类)。

解决方案可能如下所示:

assertThat(list).hasOnlyElementsOfType(B.class).hasSize(1);
于 2017-04-14T20:56:54.093 回答
13

I would use AssertJ extracting feature as is:

assertThat(list).extracting("class")
                .containsOnlyOnce(B.class);
于 2016-05-14T09:36:15.877 回答
5

您需要定义一个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);
于 2016-05-13T10:02:52.573 回答
3

您的代码的问题在于 is 的类型listA但您尝试验证的元素的类型containsOnlyOnceis Class<B>

您需要使用相应的类型。例如,您可以提取列表中的类:

Stream<Class<?>> classes = list.stream().map(x -> x.getClass());
Assertions.assertThat(classes).containsOnlyOnce(B.class);
于 2016-05-13T09:19:49.450 回答