首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >@SpringBootTest使用MapStruct需要Impl

@SpringBootTest使用MapStruct需要Impl
EN

Stack Overflow用户
提问于 2020-11-05 10:53:16
回答 3查看 1.3K关注 0票数 1

我有以下测试:

代码语言:javascript
运行
复制
@SpringBootTest(classes = {SomeService.class, DtoMapperImpl.class})
class SomeServiceTest {

下列地图绘制者:

代码语言:javascript
运行
复制
@Mapper(componentModel = "spring")
public interface DtoMapper {
    EntityDto toDto(Entity entity);
}

我不会更改包(这意味着DtoMapperImplDtoMapper在同一个包中)

一旦我更改Impl接口,我的测试就失败了:

代码语言:javascript
运行
复制
@SpringBootTest(classes = {SomeService.class, DtoMapper.class})
class SomeServiceTest {

由: org.springframework.beans.factory.UnsatisfiedDependencyException:错误创建名为“someService”的bean引起的

:通过构造函数参数2表示的不满意的依赖关系;嵌套的异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:,没有“DtoMapper”类型的限定bean :预期至少有一个bean,它可以作为自动选择。依赖性注释:{}

你能建议解决这个问题的最佳方法吗?我在MapStruct 1.3.1.最后

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2020-11-06 07:48:21

这个问题实际上与MapStruct无关,而是与如何使用SpringBootTest#classes有关。

classes in SpringBootTest是为了提供应该用于在测试中加载的组件。

来自JavaDoc:

用于加载ApplicationContext的组件类。也可以使用@ContextConfiguration(classes=...)指定。如果未定义显式类,则在返回到@Configuration搜索之前,测试将查找嵌套的@SpringBootConfiguration类。返回:用于加载应用程序上下文的组件类。

在您的例子中,您有两个类:

  • SomeService --我假设它是一个带有@Service注释的类,Spring将正确地加载it
  • DtoMapper --这是一个MapStruct映射器,它是一个接口,而不是一个组件。您需要用于测试的组件是DtoMapperImpl

您有几种方法可以解决这个问题:

使用Impl类

您可以在DtoMapperImpl中使用SpringBootTest#classes ( Spring类),然后您的测试将加载正确的组件

使用将组件扫描映射程序的自定义配置类。

代码语言:javascript
运行
复制
@TestConfiguration
@ComponentScan("com.example.mapper")
public class MappersConfig {

}

然后在您的SpringBootTest#classes中使用这个。例如。

代码语言:javascript
运行
复制
@SpringBootTest(classes = {SomeService.class, MappersConfig.class})
class SomeServiceTest {
   ...
}
票数 2
EN

Stack Overflow用户

发布于 2020-11-05 16:17:42

创建以下配置(应该指向映射器所在的位置):

代码语言:javascript
运行
复制
@TestConfiguration
@ComponentScan("some.package.mapper")
public class MappersConfig {
}

并修改切片:

代码语言:javascript
运行
复制
@SpringBootTest(classes = {SomeService.class, MappersConfig.class})
class SomeServiceTest {
票数 0
EN

Stack Overflow用户

发布于 2022-12-01 23:05:15

我建议对接受的答案做一些改进,这样您就不必将包名写成硬编码字符串,而是使用ComponentScan basePackageClasses:

代码语言:javascript
运行
复制
@TestConfiguration
// @ComponentScan("some.package.mapper")
@ComponentScan(basePackageClasses = DtoMapper.class)
public class MappersConfig {
}

但是,这种方法(以及接受的答案)有一个明显的缺点:整个包将被扫描,其中可能包含不想要的类。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64695709

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档