JUnit测试。使用ModelMapper库将实体转换为DTO时的问题

时间:2019-01-15 10:53:27

标签: java junit mockito

我正在使用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());
}
}

在Service层上,我有一个从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;
}

当我尝试为此方法创建测试时,会出现问题。 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);

}
}

当我在Service层上使用BeanUtils.copyProperties(obj1,obj2);时进行转换; -测试成功通过。使用ModelMapper我得到NULL。任何想法如何解决此错误或重构代码?预先感谢

2 个答案:

答案 0 :(得分:2)

如果您有@Mock private ObjectMapperUtils modelMapper;,则默认情况下您没有真实的ObjectMapperUtils。因此,您不是在调用实现,而是在调用Mockito为您提供的默认存根。这就是为什么您从null获得modelMapper.map()返回值的原因。

要么不模拟ObjectMapperUtils bean,要么安排它使用Mockito API中的when()等进行适当的操作。

答案 1 :(得分:1)

要建立在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);

        }
    }

这是一个很容易犯的错误,重要的是要记住,所有@mock对象都不是真正的实现,并且如果您希望返回任何行为,则需要预先定义它。