Reputation: 1669
I have this method to be unit tested:
public class DPService {
public DPModel saveTreeRecursively(DPDTO dpDTO) {
DPModel dpModel = new DPModel(dpDTO.getDPKey(), dpDTO.getName());
DPModel savedDpModel = dpDAO.save(dpModel);
Long dpId = savedDPModel.getDpId();
// after some operations
return savedDpModel;
}
}
The test class is:
public class DPServiceTest {
@Test
public void testSaveTreeRecursively() {
DPModel dpModel1 = new DPModel(dpKey, dpName); // same dpKey and dpName
//used in the SUT method to create DPModel, dpModel
DPModel dpModel2 = new DPModel(dpKey, dpName);
dpModel2.setDPId(123L);
// SUT
DPService dpService = new DPService();
// creating a mock DAO so that, the unit testing is independent of real DAO
DPDaoMock dpDaoMock = Mockito.mock(DPDao.class);
// we want to control the mock dpDAO so that it returns
// the model we want that the below SUT method uses; basically we are pretending that
// the dpDAO saved the dpModel1 with a primary key, dpId = 123
// and returned the dpModel2 saved in the database.
Mockito.when(dpDaoMock.save(dpModel1)).thenReturn(dpModel2);
DPModel dpModel3 = dpService.saveTreeRecursively(dpDTO);
assertEquals(dpModel3.getDpID(), 123L);
}
}
So obviously the SUT method failed at line:
Long dpId = savedDPModel.getDpId();
because the instance created inside the SUT method is not the same one we want to be used from the dpDaoMock
.
So how can I overcome this problem? Is there any other better approach to mock DAO?
Thanks
Upvotes: 3
Views: 2779
Reputation: 18106
Some of the options.
The factory interface of DPModel
can be introduced as a dependency of DPService
. So that, the return value of the factory method (of the factory) can be mocked and used for the assertion.
Please refer to the Abstract factory pattern.
Mockito matchers can be used to check arguments of mock methods:
Mockito.when(dpDaoMock.save(Matchers.any())).thenReturn(dpModel2);
or more strict example:
Mockito.when(dpDaoMock.save(Matchers.argThat(new ArgumentMatcher<DPModel>() {
@Override
public boolean matches(Object argument) {
DPModel dpModel = (DPModel) argument;
return dpModel.getDpId().equals(123L);
}
}))).thenReturn(dpModel2);
Upvotes: 2