问题
I am working on the Spring Boot web app and I have a custom realization of the ModelMapper library that allows me to convert single objects and a list of objects.
@Component
public class ObjectMapperUtils {
@Autowired
private static ModelMapper modelMapper;
static {
modelMapper = new ModelMapper();
modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
}
private ObjectMapperUtils() {
}
public <D, T> D map(final T entity, Class<D> outClass) {
return modelMapper.map(entity, outClass);
}
public <D, T> List<D> mapAll(final Collection<T> entityList, Class<D> outCLass) {
return entityList.stream().map(entity -> map(entity, outCLass)).collect(Collectors.toList());
}
}
On the Service layer, I have a method returns from DB UserEntity object and convert it to UserDTO.
@Autowired
private UserRepository userRepository;
@Autowired
private ObjectMapperUtils modelMapper;
@Override
public UserDTO getByUserId(String userId) {
UserEntity userEntity = userRepository.findByUserId(userId)
.orElseThrow(() -> new NotFoundException("User with userId[" + userId + "] not found"));
//UserDTO userDTO = new UserDTO();
//BeanUtils.copyProperties(userEntity, userDTO);
return modelMapper.map(userEntity, UserDTO.class); // userDTO;
}
The problem occurs when I try to create a test for this method. UserDTO always returned as NULL value.
class UserServiceImplTest {
@InjectMocks
private UserServiceImpl userService;
@Mock
private UserRepository userRepository;
@Mock
private ObjectMapperUtils modelMapper;
@BeforeEach
void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
@Test
void testGetByUserId() {
UserEntity userEntity = new UserEntity();
userEntity.setId(1L);
userEntity.setUsername("zavada");
userEntity.setUserId("33b4c069-e907-45a9-8d49-2042044c56e0");
when(userRepository.findByUserId(anyString()))
.thenReturn(Optional.of(userEntity));
UserDTO userDTO = userService.getByUserId("33b4c069-e907-45a9-8d49-2042044c56e0");
System.out.println(userDTO); <--- NULL
assertEquals("zavada", userDTO.getUsername());
assertNotNull(userDTO);
}
}
When I use on the Service layer converting by BeanUtils.copyProperties(obj1, obj2); - the test is passed successfully. With ModelMapper I get NULL. Any ideas how to solve this error or refactor code? Thanks in advance
回答1:
To build upon user268396 answer you would need the following to get this to work:
@RunWith(MockitoJUnitRunner.class)
public class StackOverflowTest {
@InjectMocks
private StackOverflow userService = new StackOverflow();
@Mock
private UserRepository userRepository;
@Mock
private ObjectMapperUtils modelMapper;
private UserDTO userDTO = new UserDTO();
private UserEntity userEntity = new UserEntity();
@Before
public void setUp() {
when(modelMapper.map(any(), any())).thenReturn(userDTO);
userDTO.setId(1L);
userDTO.setUsername("zavada");
userDTO.setUserId("33b4c069-e907-45a9-8d49-2042044c56e0");
}
@Test
public void testGetByUserId() throws Throwable {
when(userRepository.findByUserId(anyString())).thenReturn(Optional.of(userEntity));
UserDTO result = userService.getByUserId("33b4c069-e907-45a9-8d49-2042044c56e0");
System.out.println(result);
assertEquals("zavada", result.getUsername());
assertNotNull(result);
}
}
This is quite an easy mistake to make, it is important to remember that all you @mock
ed objects are not real implementations anymore and if you expect any behaviour back you would need to define it upfront.
回答2:
If you have a @Mock private ObjectMapperUtils modelMapper;
then by default you do not have a real ObjectMapperUtils
. So you are not calling your implementation, you are calling the default stubs that Mockito provides for you. That is why you are getting a null
return value from modelMapper.map()
.
Either do not mock the ObjectMapperUtils
bean or arrange for it to do something suitable using when()
etc. from the Mockito API.
来源:https://stackoverflow.com/questions/54197442/junit-test-the-problem-when-converting-entity-to-dto-by-using-modelmapper-libra