Reputation: 3032
Here is my problem:
public interface Containter extends ModelElement{
List<? extends ModelElement> getChildren();
}
There are several classes implementing Containter, and I want to mock them:
public class MockMama {
public static <T extends Containter, Y extends ModelElement> T bornContainer(Class<T> clazz, Y ... children) {
T container = mock(clazz);
when(container.getChildren()).thenReturn(Arrays.asList(children));
return container;
}
}
But this doesn't work. Eclipse says "The method thenReturn(List) in the type OngoingStubbing> is not applicable for the arguments (List)". I've also tried to pass locally declared variable of type List<? extends ModelElement>
to thenReturn but this didn't help either.
Any help is highly appreciated and welcomed :)
Upvotes: 0
Views: 6068
Reputation: 79876
Your problem is that there's no guarantee that the type returned by getChildren() matches the type of the varargs argument to your bornContainer method. So the compiler is right to complain about this. Using an intermediate local variable is really turning the compiler error into a potential runtime problem.
It seems to me that your "Containter" should really be a generic class, because its behaviour depends on the type that's in the list that getChildren() returns. Have a look at my rewrite of your example. This has no compile errors or warnings.
public interface Containter<Z extends ModelElement> extends ModelElement{
List<Z> getChildren();
}
public class MockMama {
public static <Y extends ModelElement, T extends Containter<Y>> T bornContainer( Class<T> clazz, Y ... children) {
T container = mock(clazz);
when(container.getChildren()).thenReturn( Arrays.asList(children));
return container;
}
}
Hope this helps.
Upvotes: 2
Reputation: 42283
Usually in tests you can disregard unchecked or raw type warnings. So it is usually safe to annotate your test with a compiler directive such as @SupressWarning("unchecked")
.
Upvotes: 0