当前位置: 首页 > 知识库问答 >
问题:

MapStruct Spring Junit:将mapper注入服务类测试

洪旻
2023-03-14

我使用的是Spring Boot、MapStruct(1.5.3.Final)和JUnit。我想将映射器注入到服务类测试中。我不想存根这个映射器(当(..).然后返回(…))。

我已经尝试了很多东西,并阅读了Stackoverflow上的多个帖子,但我什么也没找到。

我的Mapper:

@Mapper(
        componentModel = MappingConstants.ComponentModel.SPRING,
        injectionStrategy = InjectionStrategy.CONSTRUCTOR
)
public interface ReservationMapper {

    @Mapping(target = "id", ignore = true)
    Reservation getReservationFrom(NewReservationSentByClient reservationData);

    ExistingReservation getExistingReservationFrom(Reservation reservation);
}

使用此映射器的服务:

@Service
@RequiredArgsConstructor
@Slf4j
public class StandardReservationService implements ReservationService{
    private final ReservationMapper reservationMapper;
  ...

测试类

@RunWith(SpringRunner.class)
@SpringBootTest(classes={ReservationMapper.class})
public class StandardReservationServiceTest {

    @MockBean
    private ReservationRepository reservationRepositoryMock;
    @Autowired
    private ReservationMapper reservationMapperMock;
    @MockBean
    private ReservationRulesRepository reservationRulesRepositoryMock;
    @Autowired
    private StandardReservationService service;


    @ParameterizedTest
    @EnumSource(ReservationSource.class)
    public void ...

pom.xml

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>${org.mapstruct.version}</version>
        </dependency>

        <!-- TESTS -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <build>
        <plugins>

            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.17</source>
                    <target>1.17</target>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${org.mapstruct.version}</version>
                        </path>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>${lombok.version}</version>
                        </path>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok-mapstruct-binding</artifactId>
                            <version>0.2.0</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>

        </plugins>
    </build>

我试过:

  • 在@SpringBootTest中传递ReserveMapperImpl.class(class={..}),但当我清理安装时,找不到该实现
  • 手动安装ReserveMapperImpl,但在清理安装时出现相同问题
  • 。。。等等

如果可能的话,我不想使用@SpringBootTest,因为我正在编写单元测试,所以我不需要上下文…但是我不想手动创建对象映射和存根。

共有2个答案

秦禄
2023-03-14

你应该试试

private ReservationMapper reservationMapper = Mappers.getMapper(ReservationMapper.class);

并删除@Autowired注释。它应该给你映射器的真正实现。

韶云瀚
2023-03-14

我认为您没有机会只能使用带有Spring上下文的测试,因为您使用的是Spring组件模型。我认为问题是,实际测试不会扫描映射器的实现(ReservationMapperImpl)。

我建议您在映射器的包上使用组件扫描进行测试。为此,您不需要使用@SpringBooTest,也可以使用@SpringJunitConfig(TestMappingConfig.class)和如下示例测试配置

@ComponentScan("package.of.the.mapper")
public class YouTestMappingConfig {

}

这将扫描两个,不会拾取的预订映射器,因为它没有@Component|客户服务|Bean 注释,但 ReservationMapperImpl 具有@Component注释,并将为您的测试应用程序上下文选取。

 类似资料:
  • 问题内容: 我在Groovy中实现了Grails服务,我想在Web应用程序中将其注入Java类。我知道我可以通过applicationContext.getBean(“ exampleService”)获得Java中的bean,但是在编译时类型ExampleService是未知的。 我可以简单地导入服务吗?它似乎没有声明一个典型的包。 (我对Grails和Java Web还是很陌生,因此非常感谢能

  • 我有个问题..我正在创建一个aspectj类,在我的类中我需要访问一个spring-boot服务,但是当我尝试使用@AutoWired或通过构造函数注入它时,我出现了一个错误: 有人能帮帮我吗?

  • 问题内容: 我写了一个AngularJS服务,我想对其进行单元测试。 我的app.js文件已注册: 我可以测试DI是否像这样工作: 这证明了可以通过DI框架创建服务,但是接下来我要对服务进行单元测试,这意味着要模拟注入的对象。 我该怎么做呢? 我试过将我的模拟对象放在模块中,例如 并将服务定义重写为: 但是后者似乎停止了DI所创建的所有服务。 有人知道我可以如何为单元测试模拟注入的服务吗? 谢谢

  • 问题内容: 我正在测试服务A,但是服务A取决于服务B(即服务B已注入服务A)。 我已经看到了这个问题,但是我的情况有所不同,因为我认为_模拟_ 服务B而不是注入服务B的实际实例更有意义。我将用茉莉间谍对其进行模拟。 这是一个示例测试: 我得到的错误是: 错误:未知提供程序:serviceBProvider 我该怎么做? 问题答案: 实际上,在AngularJS中,依赖注入使用“最后获胜”规则。因此

  • 我不确定DI应该如何与服务类一起工作。基本上,这两个服务类具有相同的接口,我希望能够避免nessesary if的,如果我可以将正确的一个注入到控制器中。一个例子将非常感谢。 抱歉,伙计们,我不太清楚。我还需要弄清楚的是,哪一个服务类需要注入到控制器中,而不需要在那一点上指定具体的实现。所以,我希望有一种方法可以执行某种if语句,并检查应该插入服务的哪个实现。

  • 问题内容: 是否可以在angularJS中将一个服务注入到另一个服务中? 问题答案: 是。遵循angularjs中的常规注入规则。 感谢@simon。最好使用数组注入以避免最小化问题。

  • 我有一些UserService对用户实体进行操作。我创建了自己的注释和ConstraintValidator类作为实现 我需要将UserService注入到ConstraintValidator中。而且,正如spring文档所说,在注册bean之后: 不幸的是,它对我没有作用。我在字段(在实现ConstraintValidator的类内)使用NullPointerException累加stackt