[英]JUnit test. The problem when converting entity to DTO by using ModelMapper library
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.我正在开发 Spring Boot Web 应用程序,并且我有一个 ModelMapper 库的自定义实现,它允许我转换单个对象和对象列表。
@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.在服务层,我有一个方法从 DB UserEntity 对象返回并将其转换为 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.
UserDTO 始终作为 NULL 值返回。
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);当我在服务层使用 BeanUtils.copyProperties(obj1, obj2) 转换时; - the test is passed successfully.
- 测试成功通过。 With ModelMapper I get NULL.
使用 ModelMapper 我得到 NULL。 Any ideas how to solve this error or refactor code?
任何想法如何解决此错误或重构代码? Thanks in advance
提前致谢
If you have a @Mock private ObjectMapperUtils modelMapper;
如果您有
@Mock private ObjectMapperUtils modelMapper;
then by default you do not have a real ObjectMapperUtils
. 那么默认情况下,您没有真正的
ObjectMapperUtils
。 So you are not calling your implementation, you are calling the default stubs that Mockito provides for you. 因此,您不是在调用实现,而是在调用Mockito为您提供的默认存根。 That is why you are getting a
null
return value from modelMapper.map()
. 这就是为什么您从
modelMapper.map()
获得null
返回值的modelMapper.map()
。
Either do not mock the ObjectMapperUtils
bean or arrange for it to do something suitable using when()
etc. from the Mockito API. 要么不模拟
ObjectMapperUtils
bean,要么使用Mockito API中的when()
等安排它进行适当的处理。
To build upon user268396 answer you would need the following to get this to work: 要建立在user268396答案的基础上,您需要执行以下操作才能使其工作:
@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. 这是一个很容易犯的错误,重要的是要记住,所有
@mock
ed对象不再是真正的实现,并且如果您期望任何行为都需要预先定义。
For the same situation, you could also do对于同样的情况,你也可以这样做
So your setup method will look something like this ,所以你的设置方法看起来像这样,
@InjectMocks
private UserServiceImple userServiceImpl;
@Mock
private UserRepository userRepository;
private ObjectMapperUtil objectMapperUitl; // not mocked
@BeforeEach
public void init() {
objectMapperUitls = new ObjectMapperUtils();
userServiceImple.setMapper(objectMapperUitls);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.