My Utils class has an init method dependent upon external resources (e.g., a database connection) that I am unsuccessfully mocking with Mockito. Utils seems like it can be share across instance of my application, so is declared as a static (i.e., a class variable) in
public class EmailNotificationWorkItemHandler extends AbstractLogOrThrowWorkItemHandler {
private static Utils utils = new Utils();
public void executeWorkItem(WorkItem workItem, WorkItemManager manager) {
// Throw an error due to many missing parameters on the workitem
String id= (String) workItem.getParameter("ID");
...
try {
RequiredParameterValidator.validate(this.getClass(), workItem);
...
} catch (Throwable e) {
utils.insertErrors(id, errorCode, errorMessage, e.getStackTrace(), -1L); // testing this method called
}
...
}
I realize I could use dependency injection for Utils but am avoiding Spring. Postings about mocking static fields make me feel like I am close:
@Test
public void executeWorkItemMissingParametersTest() {
Utils mockUtils = mock(Utils.class);
WorkItemManager mockWorkItemMgr = mock(WorkItemManager.class);
EmailNotificationWorkItemHandler mockWorkItemHandler = mock(EmailNotificationWorkItemHandler.class);
doAnswer(new Answer<Void>() {
public Void answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
System.out.println("called with arguments: " + Arrays.toString(args));
return null;
}
}).when(mockUtils).insertErrors(any(), any(), any(), any(), anyLong());
try {
doAnswer(new Answer<Void>() { // Unfinished stubbing detected
public Void answer(InvocationOnMock invocation) {
return null;
}
}).when(mockUtils);
Utils.init();
} catch (Exception e) {
System.out.println("In mocking of Utils.init() " + e.getLocalizedMessage());
}
WorkItemImpl workItem = new WorkItemImpl();
workItem.setParameter("ID", "1111-AAAA");
// Lots of required parameters removed to cause an exception and insertErrors to be called
mockWorkItemHandler.executeWorkItem(workItem, mockWorkItemMgr);
verify(mockUtils).insertErrors(any(), any(), contains("RequiredParameterValidator"), any(), anyLong());
}
But a real instance of Utils is being used and called in mockWorkItemHandler - not the mocked Utils - and an "Unfinished stubbing detected" exception occurs where labeled above. My goal is to test the calling of utils.insertErrors as commented in the code and to do this without Utils' side effects. What am I missing in my mocks to (1) use a mocked Utils (without side effects, such as database connections) and (2) to test that mockWorkItemHandler's utils.insertErrors is called to record the missing parameters?
Please note that I have shown what seem to be all the relevant parts of EmailNotificationWorkItemHandler and Utils.