断言两个 List 按特定顺序具有相同的子类型

Assert two List have same subtypes in a certain order

我想根据预期的列表检查两个列表(比方说 ArrayLists)是否具有完全相同的实例 类。 为此,我构建了下一个方法,但我想知道是否有另一种使用某些库的奇特方法,比如 assertJ。

    private void assertConcreteTypes(List actual, List expected) {
        for (int i = 0; i < actual.size(); i++){
            assertThat(actual.get(i)).isExactlyInstanceOf(expected.get(i).getClass());
        }
    }

我们非常欢迎任何建议。谢谢!

您需要考虑不同大小的列表以及列表中的空元素。

这看起来很易读并且适合这些边缘情况:

private void assertConcreteTypes(List actual, List expected) {
    assertEquals(classes(expected), classes(actual));
}

private List<Class<?>> classes(List<Object> list) {
    return list.stream().map(v -> v == null ? null : v.getClass()).collect(Collectors.toList());
}

您可以创建一个自定义的 Assertj 断言器,并且可以利用它来断言类型。

class TypeAssert extends AbstractAssert<TypeAssert, List<?>> {

    public TypeAssert(List<?> actual) {
        super(actual, TypeAssert.class);
    }

    public TypeAssert hasElementsOfExactlyTheSameTypeAs(List<?> expected) {
        isNotNull();
        for (int i = 0; i < actual.size(); i++) {
            if (!actual.get(i).getClass().equals(expected.get(i).getClass())) {
                failWithMessage("Expected [%s]th element to be of type: %s but was of type: %s",
                    i, expected.get(i).getClass(), actual.get(i).getClass());
            }
        }

        return this;
    }
}

您需要一个静态方法来公开我们的自定义导出器的对象。

class Assertions {

    // static factory method which exposes custom asserted
    static TypeAssert assertThat(List<?> actual) {
        return new TypeAssert(actual);
    }
}

然后就可以使用上面的方法进行基于类型的断言了

List<Object> actual = List.of(new Employee());
List<Object> expected = List.of(new StringBuilder());

Assertions.assertThat(actual).hasElementsOfExactlyTheSameTypeAs(expected);

如果您仅在 1 或 2 个地方基于类型进行断言,那么我将填写您提到的方法,该方法更加清晰易读。但是,如果您需要在多个地方进行此类断言,那么我建议您创建一个自定义断言器。