Search code examples
javaunit-testingjunitmockitoinvocationtargetexception

UnfinishedStubbingException received for JUnit test


Hi I am trying to test a method with Mockito and received the UnfinishedStubbingException. I am new to Mockito and not sure if I am doing something terrific :)

These are my stubs

 @InjectMocks
Constants constants;

@Mock
PreGeneratedAccountRepository preGeneratedAccountRepository;

@InjectMocks
PopulateUnqiueAccountNumber populateUnqiueAccountNumber;

@Before
public void setUp() throws Exception {
    MockitoAnnotations.initMocks(this);
}

and my test method

 @Test
public void testCheckAvailableAccountNumbersForSuccess() throws Exception {

    populateUnqiueAccountNumber.setMinCount(2);
    populateUnqiueAccountNumber.setInsertRecordCount(2);

    long preGeneratedRowCount = 1;
    long preGeneratedAccountCount = 0;
    long accountNum = 8609024563l; 

    PreGeneratedAccount preGeneratedAccount = new PreGeneratedAccount();

    when(preGeneratedAccountRepository.countByAcctNumAvailableFlag(Constants.FALSE)).thenAnswer(new Answer<Long>() {
        @Override
        public Long answer(InvocationOnMock invocation) throws Throwable {              
            return preGeneratedRowCount;
        }
    });
    when(preGeneratedAccountRepository.countByAccountNum(accountNum)).thenAnswer(new Answer<Long>() {
        @Override
        public Long answer(InvocationOnMock invocation) throws Throwable {              
            return preGeneratedAccountCount;
        }
    });
    when(preGeneratedAccountRepository.saveAndFlush(preGeneratedAccount));

    // call testing method
    populateUnqiueAccountNumber.checkAvailableAccountNumbers();

    // Verify the mock calls
    verify(preGeneratedAccountRepository, times(1)).countByAcctNumAvailableFlag(Constants.FALSE);
    verify(preGeneratedAccountRepository, times(1)).countByAccountNum(accountNum);
    verify(preGeneratedAccountRepository, times(1)).saveAndFlush(preGeneratedAccount);

}

and my service method

 @Scheduled(cron = "${app.config.cron.rate}")
public void checkAvailableAccountNumbers() {
    LOGGER.debug("Method execution started :: " + new Date());

    try {
        long rowCount = preGeneratedAccountRepository.countByAcctNumAvailableFlag(Constants.FALSE);
        LOGGER.debug("Available account numbers in Database" + rowCount);

        int totalRecordInserted = 0;

        if (rowCount < minCount) {
            do {
                int count = insertRecordCount - totalRecordInserted;
                LOGGER.debug("Number of Record need to insert::" + count);
                int recordInserted = insertAccountNumbers(count);
                totalRecordInserted = totalRecordInserted + recordInserted;
                LOGGER.debug("totalRecordInserted::" + totalRecordInserted);
            } while (totalRecordInserted < insertRecordCount);
        }
    }

    catch (DataAccessException e) {
        LOGGER.error("An exception was encountered when inserting account numbers", e);
        throw e;
    }
    LOGGER.debug("Method execution ended :: " + new Date());
}

I am receiving error at this line in my service

preGeneratedAccountRepository.countByAcctNumAvailableFlag(Constants.FALSE);

Exception

    Unfinished stubbing detected here:
-> at com.cardinalhealth.chh.batch.PopulateUnqiueAccountNumberTest.testCheckAvailableAccountNumbersForSuccess(PopulateUnqiueAccountNumberTest.java:80)

E.g. thenReturn() may be missing.
Examples of correct stubbing:
    when(mock.isOk()).thenReturn(true);
    when(mock.isOk()).thenThrow(exception);
    doThrow(exception).when(mock).someVoidMethod();
Hints:
 1. missing thenReturn()
 2. you are trying to stub a final method, you naughty developer!
 3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed

Any help is appreciated :)


Solution

  • Your problem is this line.

    when(preGeneratedAccountRepository.saveAndFlush(preGeneratedAccount));
    

    You haven't specified what you want Mockito to do when this method is called.

    Note also that you've used Answer twice when you don't need to. You can just use thenReturn each time you've used an Answer, for example,

    when(preGeneratedAccountRepository.countByAcctNumAvailableFlag(Constants.FALSE)).thenReturn(pregeneratedAccountCount);