I would like to assert whether every element of an array is a sub type of a particular class. So I wrote a helper like this:
private <T> void assertContainsAllSubtypes(
List<? extends T> list,
Class<? extends T>... expectedSubtypes) {
Set<Class<? extends T>> subtypeSet =
new HashSet<>(Arrays.asList(expectedSubtypes));
assertThat(list)
.isNotEmpty()
.hasSize(subtypeSet.size())
.extracting(T::getClass)
.containsExactlyInAnyOrderElementsOf(subtypeSet); <-- ERROR
}
But I get the following error:
Required type:
Iterable
<? extends Class<capture of ? extends T>>
Provided:
Set
<Class<? extends T>>
What am I missing?
Thanks.
getClass()
call and usehasOnlyElementsOfTypes()
instead. i believe the problem with your current version is that usingObject::getClass
loses any type information from your generic parameters..hasSize(subtypeSet.size())
looks suspicious. I don't think it's related to the error, but becausesubtypeSet
is aSet
, it does mean that your assertion can be satisfied only byList
s whose elements are all of different classes from each other.hasSize()
assertion is redundant with thecontainsExactlyInAnyOrderElementsOf()
assertion, which is stronger. And theisNotEmpty()
seems redundant too, except inasmuch asisNotEmpty()
makes it impossible for an empty list to satisfy the assertion even in the event that zeroexpectedSubtypes
are provided.T::getClass
instead ofObject::getClass
? You don't need to preserve theT
here, because in practice, anyClass
object is acceptable. Indeed, I don't follow why the method needs to be generic at all, but surely any point to that is satisfied by type checking at the point of invocation.