1

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 :)

user09
  • 920
  • 2
  • 12
  • 38

1 Answers1

2

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);
Dawood ibn Kareem
  • 77,785
  • 15
  • 98
  • 110
  • Also, I don't understand the need of `@InjectMocks` on the `Constants` here. – user2004685 Jan 05 '17 at 18:33
  • But when I debug it is breaking at this line preGeneratedAccountRepository.countByAcctNumAvailableFlag(Constants.FALSE); in my service. FYI, first I tried the way you mentioned for return but getting the same error. SO I changed to Answer to see if it fix the problem but no luck @DavidWallace – user09 Jan 05 '17 at 18:40
  • If it breaks for when(preGeneratedAccountRepository.saveAndFlush(preGeneratedAccount)); this then it has to break while I am in my test method while debugging but it doesn't. It passed the step there and my control goes to service class method and failed there – user09 Jan 05 '17 at 18:41
  • Yes. That's what happens with unfinished stubbing. Mockito is still waiting to find out what you want to have happen on a call to `saveAndFlush`. Mockito can't know that you've failed to stub correctly until you start running your test, and call a method on a mock. – Dawood ibn Kareem Jan 05 '17 at 18:43
  • Forget the second half of my answer for now - first, just fix the line I told you to fix. Supply a `thenReturn` or `thenAnswer` for `when(preGeneratedAccountRepository.saveAndFlush(preGeneratedAccount))`. That's what's causing your problem. – Dawood ibn Kareem Jan 05 '17 at 18:44
  • That's solved the problem. Now I understand the exception and the behavior of Mockito for this exception. Thanks @DavidWallace – user09 Jan 05 '17 at 18:50