Search code examples
javaspringjunitmockitomatcher

Java Mockito InvalidUseOfMatchersException when mocking method


I'm having difficulty testing methods with mockito 2.23.4, junit4 and springrunner. I keep getting InvalidUseOfMatchersException even though the code looks perfectly fine to me. I'm not sure what exactly I'm missing. Any tips would be very helpful to me. I'll post the code below.

    @RunWith(SpringRunner.class)
    public class FiscalClosingServiceImplTest {
        @InjectMocks
        private FiscalClosingServiceImpl fiscalClosingServiceImpl;
        @Mock
        private IDataBeanManager dataBeanManager;
        @Mock
        private IFiscalClosingPopulator fiscalClosingPopulator;
        @Mock
        private DataBean dataBean;
        @Test
        public void test_getFiscalClosingListByNodeIdAndSiteId_WhenListNotEmpty() throws ServiceException {
            //Arrange
            List<DataBean> dataBeansResult = new ArrayList<DataBean>();
            dataBeansResult.add(dataBean);
            when(dataBeanManager.listBeansByAttributeValue(anyString(), anyString(), anyString(), anyString())).thenReturn(dataBeansResult);
            String siteId = "siteId";
            FiscalClosing fiscalClosingTest = new FiscalClosing();
            fiscalClosingTest.setSiteId(siteId); 
 when(fiscalClosingPopulator.convertBeanToFiscalClosing(any(DataBean.class))).thenReturn(fiscalClosingTest);

        //Act
        List<FiscalClosing> result = fiscalClosingServiceImpl.getFiscalClosingListByNodeIdAndSiteId(anyString(), eq(siteId));

        //Assert
        assertEquals(result.get(0).getSiteId(), fiscalClosingTest.getSiteId());
    }
}

Method to be tested below:

@Override
    public List<FiscalClosing> getFiscalClosingListByNodeIdAndSiteId(final String nodeId, final String siteId)
            throws ServiceException {
        log.debug("Retrieving FiscalClosing by transactionLastUpdatedDateTime");
        List<FiscalClosing> fiscalClosingList = new ArrayList<FiscalClosing>();

        List<DataBean> dataBeans = dataBeanManager.listBeansByAttributeValue(
                EntityConstant.getConstant(CONSTANTS.FISCAL_CLOSING_ID),
                EntityConstant.getConstant(CONSTANTS.FISCAL_CLOSING_NODE_ID_ID), nodeId, "");

        if(dataBeans.isEmpty()) {
            return fiscalClosingList; 
        }

        for(DataBean dataBean : dataBeans) {
            FiscalClosing fiscalClosing = fiscalClosingPopulator.convertBeanToFiscalClosing(dataBean);
            fiscalClosingList.add(fiscalClosing);
        }

        return fiscalClosingList.stream().filter(item -> item.getSiteId().equals(siteId)).collect(Collectors.toList());
    }

Solution

  • In the "Act" part of your test, you are using argument matchers as parameters of the method under test:

    List<FiscalClosing> result = fiscalClosingServiceImpl.getFiscalClosingListByNodeIdAndSiteId(anyString(), eq(siteId));
    

    You can't use matchers like this, they should be used to define the behavior of the mock in a more generic way. When calling the method you should pass actual values, although they don't have to be valid depending on how you're mocking the rest of the method.

    In your case it could be as simple as this:

    List<FiscalClosing> result = fiscalClosingServiceImpl.getFiscalClosingListByNodeIdAndSiteId("nodeId", "siteId");
    

    Then you might have to update your test to ensure that the correct site id is returned.