java - MapStruct 不会通过 Spring-boot 测试 Gradle Junit5 自动写入

标签 java spring-boot mapstruct

我正在尝试将 mapstruct 与 Gradle 一起使用,但取得的成功有限。当我在应用程序中使用它时,一切似乎都工作正常,但是当我尝试编写一些测试时,Spring 无法正确 Autowiring MapStruct (它只返回 NullPointer 异常)。我正在使用 Gradle 5.4.1、Junit5 和 IntelliJ 2019.1.2。

这是构建文件夹,没有为测试类生成映射器。

enter image description here

包含代码的存储库在这里: https://github.com/MirkoManojlovic/mapstruct-example

映射器:

@Mapper(unmappedTargetPolicy = ReportingPolicy.WARN,
        componentModel = "spring",
        injectionStrategy = InjectionStrategy.CONSTRUCTOR)
public interface ItemMapper {
    ItemDto toDto(Item item);
    Item toItem(ItemDto itemDto);
}

存储库:

public class ItemRepository {
    public ItemDto getItemDto() {
        return new ItemDto("item 1");
    }

    public Item getItem() {
        return new Item(1, "item 1", 20);
    }
}

服务:

@Service
@RequiredArgsConstructor
@Log4j2
public class ItemService {
    private final ItemRepository itemRepository;
    private final ItemMapper itemMapper;

    public ItemDto getItemDto() {
        Item item = itemRepository.getItem();
        ItemDto itemDto = itemMapper.toDto(item);
        log.info(itemDto);
        return itemDto;
    }

    public Item getItem() {
        ItemDto itemDto = itemRepository.getItemDto();
        Item item = itemMapper.toItem(itemDto);
        log.info(item);
        return item;
    }
}

测试:

@ExtendWith(MockitoExtension.class)
public class ItemServiceTest {

    @Mock
    private ItemRepository itemRepository;

    @InjectMocks
    private ItemService itemService;

    @Spy
    private ItemMapper itemMapper;

    @Test
    void shouldReturnItemDto() {
        Item mockItem = new Item(1, "mockItem", 10);
        given(itemRepository.getItem()).willReturn(mockItem);
        ItemDto itemDto = itemService.getItemDto();
        assertThat(mockItem.getName()).isEqualTo(itemDto.getName());
    }

}

构建.gradle:

plugins {
    id 'org.springframework.boot' version '2.1.5.RELEASE'
    id 'java'
}

apply plugin: 'io.spring.dependency-management'

group = 'com.mapstruct.spring.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

test {
    useJUnitPlatform {
    }
}

dependencies {
    // Mapstruct
    implementation 'org.mapstruct:mapstruct:1.3.0.Final'
    annotationProcessor 'org.mapstruct:mapstruct-processor:1.3.0.Final'
    testAnnotationProcessor 'org.mapstruct:mapstruct-processor:1.3.0.Final'

    implementation 'org.springframework.boot:spring-boot-starter-web'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'

    testImplementation('org.springframework.boot:spring-boot-starter-test')

    // JUnit5
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.2'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.3.2'
    testImplementation 'org.junit.jupiter:junit-jupiter-params:5.3.2'

    // Mockito
    testImplementation 'org.mockito:mockito-core:2.23.4'
    testImplementation 'org.mockito:mockito-junit-jupiter:2.23.4'
}

最佳答案

@Spy 注释

@Spy
private ItemMapper itemMapper;

不会对生成的ItemMapperImpl类文件执行依赖注入(inject)。解决方案是设置

 @Spy
 private ItemMapper itemMapper = Mappers.getMapper(ItemMapper.class);

或者通过@SpringBootTest(classes = {ItemMapperImpl.class})启用spring依赖注入(inject)。

关于java - MapStruct 不会通过 Spring-boot 测试 Gradle Junit5 自动写入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56341042/

相关文章:

java - 在 Eclipse 项目中使用 MapStruct 将 "dirty"字符串字段映射为 double

java - 设置轴标题并向栏中添加值

java - 获取字符串和逗号后面的值,如果有字符 '|' 则结束

postgresql - 运行测试时 Spring Boot "PSQLException: FATAL: sorry, too many clients already"

spring - 如何使用 Spring Boot 的 'spring.jackson.date-format' 属性?

java - 为什么 @HeadMapping 在 Spring MVC 中不可用?

java - 与机器人进行环聊聊天不会将消息发布到 pub/sub

java - 当出现异常时,回滚完整操作,但将异常存储在表中

java - @Mapping @Mapper 错误 不存在源参数

java-11 - Mapstruct Java11 兼容吗?