Issue
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);
}
Solution
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
Answered By - Hans-Christian
Answer Checked By - Pedro (JavaFixing Volunteer)