Assert List仅包含使用AssertJ的类的一个实例

时间:2016-05-13 09:10:59

标签: java unit-testing assertj

我可以以某种方式使用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 个答案:

答案 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);