Home > Software design >  How to mock ModelMapper for list in SpringBootTest using Junit and Mockito?
How to mock ModelMapper for list in SpringBootTest using Junit and Mockito?

Time:09-27

I have one API in which I am returning a list of DTO by mapping it with main entity object using model mapper

employeeList = employeeRepository.findAll();
employeeListPojos = employeeList.stream().map((emp) -> modelMapper.map(emp, EmployeeInfoPojo.class))
                    .collect(Collectors.toList());

I am trying to mock the model mapper in my test class but the same output is overriding in the test case

@ExtendWith(MockitoExtension.class)
public class EmployeeServiceTest {

    @Mock
    private EmployeeRepository employeeRepository;

    @Mock
    private ModelMapper modelMapper;

    @InjectMocks
    private EmployeesApiServiceImpl employeesApiService;

   EmployeeEntity employee;


    @BeforeEach
    public void setup()
    {
        employee = EmployeeEntity.builder()
                .id("1L")
                .employeeName("Test employee")
                .description("Dummy employee")
                .build();
    }

    @DisplayName("Test Case For Getting The employee Object")
    @Test
    public void givenemployeeObject_whenGetemployeeHeader_thenReturnemployeeObject()
    {
        //given - precondition or setup
       EmployeeEntity employee2 = employeeEntity.builder()
                .id("2L")
                .employeeName("Test employee 1")
                .description("Dummy employee")
                .build();

       List<EmployeeEntity> employees = new ArrayList<EmployeeEntity>();
       employees.add(employee);
       employees.add(employee2);

        BDDMockito.given(employeeRepository.findAll()).willReturn(employees);

        employeeInfoPojo convertedPojo1 = employeeInfoPojo.builder()
                .id("1L")
                .employeeName("Test employee 2")
                .description("Dummy employee")
                .build();

        EmployeeInfoPojo convertedPojo2 = employeeInfoPojo.builder()
                .id("2L")
                .employeeName("Test employee")
                .description("Dummy employee")
                .build();

        List<EmployeeInfoPojo> employeesResult = new ArrayList<EmployeeInfoPojo>();
        employeesResult.add(convertedPojo1);
        employeesResult.add(convertedPojo2);

        for(EmployeeInfoPojo co : employeesResult){
            BDDMockito.when(modelMapper.map(any(),any()))
                    .thenReturn(co);
        }


        //when - action or behaviour need to be tested
        List<EmployeeInfoPojo> result = employeesApiService.getemployeeList(null);

        System.out.println(result);

        //then - verify the output
        Assertions.assertThat(result).isNotNull();
        Assertions.assertThat(result.size()).isEqualTo(2);
    }

}

Test case is passing but output of result is not correct the convertedPojo2 is overridden in both the entries of list.

Any suggestion how to mock ModelMapper that is used with list in Junit and Mockito.

Issue mostly in these lines of EmployeeServiceTest

for(EmployeeInfoPojo co : employeesResult){
    BDDMockito.when(modelMapper.map(any(),any()))
                    .thenReturn(co);
}

CodePudding user response:

The mock for modelMapper.map(...) will always return convertedPojo2 since you don't have any specific matcher in the for-loop. Each iteration of the for-loop will override the last mock method and hence the last mock will be used.

Instead of setting up the mock in a for-loop, add the specific mock mapping, e.g something like this:

    when(modelMapper.map(eq(employee), eq(EmployeeInfoPojo.class)))
         .thenReturn(convertedPojo1);

    when(modelMapper.map(eq(employee2), eq(EmployeeInfoPojo.class)))
         .thenReturn(convertedPojo2);

This will set up a mock for the mapper when employee is used as parameter, convertedPojo1 will be returned for employee2, convertedPojo2 will be returned

  • Related