How to mock List<Interface> while using @Mock and @InjectMock
Let's say you have a Service class which is holding, List of Handler. e.g.
@Component
@RequiredArgsConstructor
public class Service {
private final List<Handler> handlerList;
Now, it's turn to write the test cases, using Junit5, and Mockito, you may be trying to write like this.
@ExtendWith(MockitoExtension.class)
class ServiceTest {
@InjectMocks
Service service;
@Mock
List<Handler> handlers;
But mockito doesn't know anything about initialising the List. So putting @Mock is not going to work.
There are 2 situations :-
Scenario 1.
You have setter method in the Service, for List<Handler> handlers;( assuming you haven't defined the List<Handler> as final)
in that case you can approach like this :-
Define all the Handler implemented(which you want use in test) class and annotate with @Mock.
Define instance of Service class(which you are going to test) and annotate with @InjectMock
Define handlers list.
In beforeEach method,
Initilize the List<Handler> with mocked classes. and set this List in Service class.
@ExtendWith(MockitoExtension.class)
class ServiceTest {
@InjectMocks
Service service;
@Mock BaseHandler baseHandler;
@Mock SpecificHandler specificHandler;
List<Handler> handlers;
@BeforeEach
void setUp() {
handlers = List.of(baseHandler, specificHandler);
service.setHandlerList(handlers);
}
Scenario 2.
You do not have setter method.
In this class you can use @Spy
Define a ArrayList<Handler> handlers;
and then add all mocked Handler to it.
these mocked instance of handler will be available in Service instance.
@ExtendWith(MockitoExtension.class)
class ServiceTest {
@InjectMocks
Service service;
@Mock BaseHandler baseHandler;
@Mock SpecificHandler specificHandler;
@Spy
ArrayList<Handler> handlers;
@BeforeEach
void setUp() {
handlers.add(baseHandler);
handlers.add(specificHandler);
}
@Test
void shouldReturnBaseHandlerContent() {
when(baseHandler.accept()).thenReturn(true);
when(baseHandler.print()).thenReturn("Hey");
String text = service.print();
assertEquals(text, "Hey");
}
}
Please note you need to define concrete class(ArrayList) not interface List for spying.
Happy Mocking.
Comments
Post a Comment