How to mock MapStruct nested mapper in JUnit5

Tags: , ,

I have been searching a solution for about a day now. I still cannot produce a working example.

My problem is simple. I have a mapper uses another mapper:

@Mapper(componentModel = "spring", uses = {RoleMapper.class})
public interface UserMapper {

     * Converts User DTO to User JPA Entity
     * @Mapping annotation is used to convert fields with different names
     * @param dto
     * @return
            @Mapping(target = "identityNo", source = "dto.userIdentity"),
            @Mapping(target = "role", source = "dto.roleDTO")
    User dtoToEntity(UserDTO dto);

     * Converts User JPA Entity to User DTO
     * @Mapping annotation is used to convert fields with different names
     * @param entity
     * @return
            @Mapping(target = "userIdentity", source = "entity.identityNo"),
            @Mapping(target = "roleDTO", source = "entity.role")
    UserDTO entityToDto(User entity);


@Mapper(componentModel = "spring")
public interface RoleMapper {

    Role roleDtoToEntity(RoleDTO dto);
    RoleDTO roleEntityToDto(Role entity);

My test class which tests mapper works as it should:

class UserMapperTest {

    private UserMapper mapper = Mappers.getMapper(UserMapper.class);

    void dtoToEntity() {

        User user = new User();
        user.setRole(new Role("ROLE_ADMIN"));

        UserDTO dto = mapper.entityToDto(user);

        Assertions.assertEquals(user.getName(), dto.getName());
        Assertions.assertEquals(user.getSurname(), dto.getSurname());
        Assertions.assertEquals(user.getIdentityNo(), dto.getUserIdentity());
        Assertions.assertEquals(user.getRole().getName(), dto.getRoleDTO().getName());

However, NullPointerException is thrown on the line where roleMapper is called in automatically generated impl class UserMapperImpl:


it comes to my basic problem, how to mock or autowire a nested mapper class?


Nested mapper is null, because Spring context is not loaded. Due to this, @Autowired is not working.

Solution is to inject nested mappers via ReflectionTestUtils.

private UserMapper mapper = UserMapperImpl.INSTANCE;

public void init() {
    RoleMapper roleMapper = Mappers.getMapper(RoleMapper.class);
    ReflectionTestUtils.setField(mapper, "roleMapper", roleMapper);

Source: stackoverflow