user656449
user656449

Reputation: 3032

mock a method with generic return type with mockito


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

Answers (2)

Dawood ibn Kareem
Dawood ibn Kareem

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

bric3
bric3

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

Related Questions