I have a base class which looks something like this:
public abstract class BaseClass implements Runnable {
final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
@Override
public void run() {
someFunction();
}
protected abstract void someFunction();
}
Then I have a child class something like this:
public class ChildClass extends BaseClass {
functionNeedsToBeTested() {
scheduler.scheduleAtFixedRate(this, 0L, 5L, TimeUnit.HOURS)
}
someFunction() {
//Does Something
}
}
Now problem comes here when I try to write a test I am not able to verify the call of scheduleAtFixedRate
method. My test looks like this:
@RunWith(MockitoJUnitRunner.class)
public class TestClass {
@Mock
private ScheduledExecutorService scheduler;
@InjectMocks
private ChildClass obj;
@Test
public void testFunc() {
obj.functionNeedsToBeTested();
Mockito.verify(scheduler).scheduleAtFixedRate(Mockito.any(ChildClass.class, Mockito.anyLong(), Mockito.anyLong(), Mockito.any(TimeUnit.class)));
}
}
Test gives me this error:
junit.framework.AssertionFailedError:
Wanted but not invoked:
scheduler.scheduleAtFixedRate(
<any>,
<any>,
<any>,
<any>
);
In your test, a mock scheduler is created, but it is not used by the object under test.
You can make the method testable if you inject the scheduler, instead of instantiating one in the base class. You could require the scheduler as an argument to the BaseClass constructor, for instance