Reputation: 352
I'm trying to make a separate method for creating a list of mocks. E.g. we have a class Entity
:
class Entity {
public List<SubEntity> subEntities;
}
But SubEntity
is interface which has two implementations:
class SubEntityA implements SubEntity {
public SomeType someProp;
}
and
class SubEntityB implements SubEntity {
public SomeAnotherType someAnotherProp;
}
so I can have in subEnities
property a mixed list of SubEntityA
and SubEntityB
objects.
In real case I have more then two types and I'd like to write a test where I need to generate a different amount of mocks of this classes and add it to the property subEntities
. I can easily crate one mock using:
mock(SubEntityA.class)
but when I'm trying to do something like this:
private List<SubEntity> getMocks(Class<? extends SubEntity> classToMock, int amount) {
List<SubEntity> mocks = new ArrayList<>();
for (int i = 0; i < amount; i++) {
mocks.add(mock(classToMock));
}
return mocks;
}
I get into trouble using e.g. List<SubEntityA> list = getMocks(SubEntityA.class, 3)
, because SubEntityA.class
or SubEntityB.class
couldn't be casted to Class<? extends SubEntity>
.
What I'm doing wrong? What shall I do to pass classes properly? I tried to find Mockito's methods but found only Mockito.anyListOf
. As I understood It won't work in my case.
Thanks!
[UPD] The test looks like:
@Mock
private RepoSubA repoA;
@Mock
private RepoSubB repoB;
@Mock
private Repo repo;
@InjectMocks
private LogicBean testee;
@Test
public void test() {
//given
List<SubEntityA> listA = getMocks(SubEntityA.class, 3);
List<SubEntityB> listB = getMocks(SubEntityB.class, 3);
List<SubEntity> list = new ArraList<>();
list.addAll(listA);
list.addAll(listB);
Rule rule = someFixture();
when(repoA.getA(rule.getId())).thenReturn(listA);
when(repoB.getB(rule.getId())).thenReturn(listB);
//when
List<SubEntity> result = testee.someMagic(rule);
//then
assertThat(result, hasSize(list.size());
}
Upvotes: 2
Views: 3569
Reputation: 444
Following is more strict and consistent as you use just the same class for return list type.
private static <T extends SubEntity> List<T> getMocks(Class<T> classToMock, int amount) {
List<T> mocks = new ArrayList<>();
for (int i = 0; i < amount; i++) {
mocks.add(mock(classToMock));
}
return mocks;
}
Upvotes: 1
Reputation: 12022
I tried to get the error but failed. This is the code I wrote.
public static class Entity {
public List<SubEntity> subEntities;
}
public static class SubEntityA implements SubEntity {
}
public static class SubEntityB implements SubEntity {
}
private List<? extends SubEntity> getMocks(Class<? extends SubEntity> classToMock, int amount) {
List<SubEntity> mocks = new ArrayList<>();
for (int i = 0; i < amount; i++) {
mocks.add(mock(classToMock));
}
return mocks;
}
@Test
public void test(){
assertEquals(3, getMocks(SubEntityA.class, 3).size());
List<SubEntityA> mocks = (List<SubEntityA>) getMocks(SubEntityA.class, 3);
assertEquals(3, getMocks(SubEntityB.class, 3).size());
}
I then executed Junit on the test method. The test passed.
EDIT: To respond to your comment, you can change the signature of your getmocks method so that the output could be cast to List<SubEntityA>
. I edited my code above and the cast works.
Upvotes: 1