thenReturn usage for generics

8,529 views
Skip to first unread message

alin.popa

unread,
Apr 7, 2010, 12:53:52 PM4/7/10
to mockito
Hi guys,

Recently I got stuck in one issue while working with mockito (1.8.0,
1.8.2, 1.8.4):
I have the following test code:

1 package org.test.mockito;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import org.junit.Test;
7 import org.junit.runner.RunWith;
8 import org.mockito.Mock;
9 import org.mockito.runners.MockitoJUnitRunner;
10
11 import static org.mockito.Mockito.when;
12 import static org.mockito.Mockito.mock;
13
14 @RunWith(MockitoJUnitRunner.class)
15 public class MockitoTest {
16 @Mock
17 private ClassToMock mock;
18
19 @Test
20 public void test(){
21 List<EnityImpl> entities = new ArrayList<EnityImpl>();
22 entities.add(new EnityImpl());
23 when(mock.getEntities()).thenReturn(entities);
24 }
25 }

Line 23 doesn't compile, using the following message: The method
thenReturn(List<capture#1-of ? extends Entity>) in the type
OngoingStubbing<List<capture#1-of ? extends Entity>> is not applicable
for the arguments (List<EnityImpl>)

Rest of the code:

1 package org.test.mockito;
2
3 import java.util.List;
4
5 public interface ClassToMock {
6 List<? extends Entity> getEntities();
7 }

1 package org.test.mockito;
2
3 public interface Entity {
4 String getText();
5 }

1 package org.test.mockito;
2
3 public class EnityImpl implements Entity {
4
5 @Override
6 public String getText() {
7 return "EnityImpl.getText()";
8 }
9
10 }

I'm pretty sure that's not an issue related to generics usage.

Is this a common situation (mistake of mine of wrong using Mockito)
that have some kind of fix, or maybe a defect in Mockito ?

Thank you,

Alin

adrian....@googlemail.com

unread,
Apr 7, 2010, 3:46:10 PM4/7/10
to mockito
I suspect this is a simple Java problem rather than anything to do
with Mockito! Try this instead:

package org.test.mockito;

import static org.mockito.Mockito.when;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class MockitoTest {
@Mock
private ClassToMock mock;

@Test
public void test() {
List<Entity> entities = new ArrayList<Entity>();
entities.add(new EntityImpl());
when(mock.getEntities()).thenReturn(entities);
}
}


package org.test.mockito;

public interface Entity {
String getText();
}

package org.test.mockito;

import java.util.List;

public interface ClassToMock {
List<Entity> getEntities();
}


package org.test.mockito;

public class EntityImpl implements Entity {

@Override
public String getText() {
return "EntityImpl.getText()";

Alin Popa

unread,
Apr 8, 2010, 2:31:36 AM4/8/10
to moc...@googlegroups.com
Thanks Adrian,

What if that getEntities() method cannot be changed ? What if that method is from a 3rd party library ?
Meanwhile I noticed that Mockito have doReturn which seems to work for my situation:

............
doReturn(entities).when(mock).getEntities();
............
public interface ClassToMock {

       List<? extends Entity> getEntities();
}
............

Should I consider that as a valid usage ? Or maybe doReturn is used in other situations ?

Thanks,

Alin

--
You received this message because you are subscribed to the Google Groups "mockito" group.
To post to this group, send email to moc...@googlegroups.com.
To unsubscribe from this group, send email to mockito+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/mockito?hl=en.



adrian....@googlemail.com

unread,
Apr 8, 2010, 6:12:07 AM4/8/10
to mockito
doReturn will work, but only because it is not type-safe, see the
javadocs.

AIUI, ? extends means classes extend Entity, not "implement" Entity.

On Apr 8, 7:31 am, Alin Popa <alin.p...@gmail.com> wrote:
> Thanks Adrian,
>

> What if that *getEntities()* method cannot be changed ? What if that method


> is from a 3rd party library ?

> Meanwhile I noticed that Mockito have *doReturn* which seems to work for my
> situation:
>
> ............
> *doReturn(entities).when(mock).getEntities();*
> ............
> *public interface ClassToMock {


>        List<? extends Entity> getEntities();}
>

> *............


>
> Should I consider that as a valid usage ? Or maybe doReturn is used in other
> situations ?
>
> Thanks,
>
> Alin
>

> On Wed, Apr 7, 2010 at 10:46 PM, adrian.p.smi...@googlemail.com <

> > mockito+u...@googlegroups.com<mockito%2Bunsu...@googlegroups.com >

Kristofer Karlsson

unread,
Apr 8, 2010, 6:41:51 AM4/8/10
to moc...@googlegroups.com
No, "? extends T" in Java works for both implementing interfaces and extending classes.


To unsubscribe from this group, send email to mockito+u...@googlegroups.com.

Stephen Duncan Jr

unread,
Apr 8, 2010, 7:16:23 AM4/8/10
to moc...@googlegroups.com
I think this is mostly a problem with how you've getEntities, using a wildcard bound in the return type.  Wildcard bounds limit what you can do with the collection, and (as in this case), cause problems for type inference.  Usually there's no reason to do so, and you can change the signature to List<Entity> getEntities();.  See http://www.angelikalanger.com/GenericsFAQ/FAQSections/ProgrammingIdioms.html#Should I use wildcards in the return type of a method?

-Stephen

--
You received this message because you are subscribed to the Google Groups "mockito" group.
To post to this group, send email to moc...@googlegroups.com.
To unsubscribe from this group, send email to mockito+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/mockito?hl=en.




--
Stephen Duncan Jr
www.stephenduncanjr.com
Reply all
Reply to author
Forward
0 new messages