use verify on mocked (with Mockito) objects inject

2020-07-30 01:47发布

问题:

I have unit test, i use guice for di, i annotate my class with :

@Guice(modules = { BatchGuiceModule4Test.class })
public class TestOneDayBatchStarter {
}

My objects are well injected from my module like this one :

@Inject
private DataManager dataManager;

In my module, I add a @Provides method :

@Provides
@Singleton
public DataManager getDataManager() {
    LOG.debug("## init Mocked Data Manager");
    DataManager dataManager = mock(DataManager.class);
    when(dataManager.getObjectCodeList()).thenReturn(getOcList());
        ....
return dataManager;
}

And in my test, i call a method which called a specific method and i want to verify it :

@Test
public void testDefaultJob() {
    JobDetail jobDetail = newJob().ofType(OneDayBatchStarter.class)
            .withIdentity(DAILY_DEFAULT_JOB, Scheduler.DEFAULT_GROUP).build();
    try {
        scheduler.scheduleJob(jobDetail, TriggerBuilder.newTrigger().startNow().build());
    } catch (SchedulerException e) {
        LOG.warn("error during scheduling", e);
    }
    verify(dataManager).getObjectCodeList();
}

I add some trace, i see that mocked object was actually called like :

"## init Mocked Data Manager "

and

"Call object code list ....."

but i have an error on verify :

FAILED: testDefaultJob
Wanted but not invoked:
dataManager.getObjectCodeList();
-> at net.test.batch.TestOneDayBatchStarter.testDefaultJob(TestOneDayBatchStarter.java:177)
Actually, there were zero interactions with this mock.

Did i miss something, or it's not possible to use mockito verify through Guice ?

回答1:

This should work, did you debug through your code? Guice should invoke your provider to get an instance of DataManager. If not, how does it get instantiated? Put a break point there and find out.



回答2:

PEBKAC problem, Guice and Mockito works perfectly, it's just that i launch job with quartz, so quartz launch the job in a new thread. And without waiting, i check if my mocked object were already called, so my problem.

So i change my test method with this

@Test
public void testDefaultJob() throws InterruptedException, Exception {
    JobDetail jobDetail = newJob().ofType(OneDayBatchStarter.class)
            .withIdentity(DAILY_DEFAULT_JOB, Scheduler.DEFAULT_GROUP).build();
    scheduler.scheduleJob(jobDetail, TriggerBuilder.newTrigger().startNow().build());
    Thread.currentThread().sleep(500);
    while (!scheduler.getCurrentlyExecutingJobs().isEmpty()) {
        Thread.currentThread().sleep(500);
    }
    verify(dataManager).getObjectCodeList();
}