'Assert two List have same subtypes in a certain order
I would like to check if two lists (let's say, ArrayLists) have exactly the same instance classes, based in an expected List. To do so, I have built the next method, but I was wondering whether there is another fancy way using certain library, like 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());
}
}
Any suggestion would be more than welcome. Thanks!
Solution 1:[1]
You can create a custom Assertj asserter and you can leverage it for asserting types.
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;
}
}
You'll need a static method that will expose the object of our Custom Exporter.
class Assertions {
// static factory method which exposes custom asserted
static TypeAssert assertThat(List<?> actual) {
return new TypeAssert(actual);
}
}
And then you can use the above method for asserting based on type.
List<Object> actual = List.of(new Employee());
List<Object> expected = List.of(new StringBuilder());
Assertions.assertThat(actual).hasElementsOfExactlyTheSameTypeAs(expected);
If you are asserting based on type only at 1 or 2 places then I fill the approach you have mentioned is much cleaner and readable. But if you need to such assertion at several places then I fill you should create a custom Asserter.
Solution 2:[2]
You need to take into account lists of different sizes as well as null elements in the lists.
This seems quite readable and caters to these edge cases:
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());
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 |