问题
I have a getter returning a List with a wildcard:
import java.util.List;
public interface Foo {
List<? extends Bar> getList();
}
Where Bar
is an other interface.
When I write an assertion with AssertJ like this:
assertThat(foo.getList()).containsExactly(bar1, bar3);
EDIT: my complete usage is to chain a usingElementComparator
and to provide a Comparator<Bar>
to compare the expected Bar
instances.
Comparator<Bar> comparator = createBarComparator()
assertThat(foo.getList()).usingElementComparator(comparator).containsExactly(bar1, bar3);
I get this compilation error:
The method containsExactly(capture#46-of ? extends Bar...) in the type ListAssert is not applicable for the arguments (Bar, Bar)
My first solution is to cast the result:
assertThat((List<Bar>)foo.getList()).containsExactly(bar1, bar3);
Then I get a warning:
Type safety: Unchecked cast from List to List
Warning can be removed with @SuppressWarnings("unchecked")
, but still the cast in the middle do not make the assertion really readable.
My second solution is to indicate the value the ELEMENT generic parameter:
Assertions.<Bar>assertThat(foo.getList()).containsExactly(bar1, bar3);
A little better, but also not that nice (no static import possible, the beginning of the line do not facilitate the readability)
I guess I am looking for an other assertThat
method for list, where the class type can be specified as second parameter:
@CheckReturnValue
public static <ELEMENT> ListAssert<ELEMENT> assertThat(List<? extends ELEMENT> actual, Class<ELEMENT> c) {
return AssertionsForInterfaceTypes.assertThat(actual);
}
This way I should be able to write something like this:
Assertions.assertThat(foo.getList(), Bar.class).containsExactly(bar1, bar3);
回答1:
That used to work with the Oracle JDK 7 compiler but this was actually a bug in the compiler, this has been fixed in Java 8 JDK so having the compilation error is the normal behavior (can't find the bug reference though).
I would be happy to support but I'm not sure this is possible in AssertJ except by removing all generics usage in collections assertions.
assertThat(List, Class) already exists but for another purpose so no luck for that option.
A possible hack is to define your own assertThat
method like that:
public static <T> ListAssert<Object> assertThat(final List<T> list) {
return Assertions.assertThat(list);
}
The trick being to return a ListAssert<Object>
.
Although I understand the rationale of the compilation error I disagree with it for read only method.
来源:https://stackoverflow.com/questions/47317425/assertj-containsexactly-assertion-on-list-with-wildcard