Home > Back-end >  DAO object not getting mocked in Service Layer using Junit 5 and Mockito
DAO object not getting mocked in Service Layer using Junit 5 and Mockito

Time:09-16

I am writing test case for service layer using JUnit 5 and Mockito. I am mocking database layer using @Mock and injecting into service layer using @InjectMocks. But, when call goes to service method, somehow mocked list from DAO is coming as empty. I am having similar kind of set up for other test classes and it is working fine. I even tried in same class by creating a simple flow which accepts a string argument and returning a string object and it worked. But somehow for this method, its not working for me. While debugging, I checked parameters are being passed as expected, its just DAO layer is giving empty list even after mocking it. Please let me know what wrong I am doing here.

Service Layer

@Service
public class XyzServiceImpl implements XyzService {

    @Autowired
    private XyzDAO xyzDAO;

   @Override
    public Map<String, String> getRecords(Map<String, String> allParams) throws Exception {
        
        String key = allParams.get("key");
        String configValue = System.getProperty(key);
        
        XyzRoot xyzRoot = new ObjectMapper().readValue(configValue, XyzRoot.class);
        List<Map<String, Object>> records = xyzDao.getRecords(xyzRoot, allParams); // list is coming as empty

        
        for (Entry<String, Object> entry : records.get(0).entrySet()) { 
            recordsMap.put(entry.getKey(), entry.getValue()!= null ? entry.getValue().toString() : "");
        }
        
        return recordsMap;
    }
}

Here is the code for test class

public class TestXyzService {
    
    @InjectMocks
    private XyzServiceImpl xyzServiceImpl;

    @Mock
    private xyzDAO xyzDao;

    private static String data = null;

    @BeforeEach
    public void init() {
        MockitoAnnotations.initMocks(this);
    }

    @BeforeAll
    public static void setUp() throws IOException {
        data = FileUtils.loadFileData("record-history.json");
    }
    

    @Test
    void getRecordTest() throws Exception {

        Gson gson = new Gson();

        Map<String, String> expectedDetails = gson.fromJson(data,
                new TypeToken<Map<String, String>>() {
                }.getType());
        Map<String, Object> recordDetailsMap = gson.fromJson(data,
                new TypeToken<Map<String, Object>>() {
                }.getType());

        List<Map<String, Object>> recordDetails = new ArrayList<>();
        recordDetails.add(recordDetailsMap);

        Map<String, String> allParams = new LinkedHashMap<>();
        allParams.put(AppConstants.PARAM_PAGE_NAME, "HISTORY_TBL");
        allParams.put(AppConstants.PARAM_ARG1, AppConstants.ARG1);

        XyzRoot xyzRoot = new XyzRoot();
        xyzRoot.setTable("TEST_TBL");

        Configuration configuration = new Configuration();
        configuration.setArgument("COL");

        xyzRoot.setConfig(configuration);

        String config = gson.toJson(xyzRoot);

        System.setProperty("key", config);

        when(xyzDao.getRecords(xyzRoot, allParams)).thenReturn(recordDetails);

        Map<String, String> actualDetails = xyzServiceImpl.getRecords(allParams); // getting error due to empty list from dao

        assertNotNull(actualDetails);
        assertEquals(expectedDetails, actualDetails);
        verify(xyzDaoDao, times(1)).getRecords(xyzRoot, allParams);
    }
}

CodePudding user response:

The object created by ObjectMapper in this line:

XyzRoot xyzRoot = new ObjectMapper().readValue(configValue, XyzRoot.class);

is an instance that is completely separated from the instance you're creating in the test:

XyzRoot xyzRoot = new XyzRoot();
xyzRoot.setTable("TEST_TBL");

You do not have an equals method implemented for XyzRoot, so simple reference equality verification (==), which is a default Object implementation inherited by all classes, returns false as the objects are two completely separate instances. That's why when(...).thenReturn(...) defined in your test is not working properly - when Mockito checks if it should fire for given object, it uses equals method by default.

To solve the problem, you should do one of the following:

  • Related