spring boot 使用哪个“切片”来测试服务组件

2024-05-19

我正在使用 spring boot 开发一个rest api。 它由标准层组成:控制器(@RestController)(处理传入的http请求并公开api端点),然后是服务层(@Service),最后是存储库层(@Repository)

我的问题是关于单元测试的。

为了测试我的控制器 - 我使用mockito模拟对服务层的调用。 另外,为了防止不必要地加载整个上下文,请阅读一些有关“弹簧切片”的内容 因此,为了测试我的控制器 - 这是使用的注释:

@WebMvcTest

@ExtendWith(SpringExtension.class)

@WebMvcTest(controllers = TieredClaimController.class)
class TieredClaimControllerTest {

    @MockBean
    private TieredClaimService tieredClaimService;

    @Autowired
    private MockMvc mockMvc;

类似地,为了测试我的 Spring 数据存储库,使用了另一个 Spring 切片注释:@DataJpaTest

@ExtendWith(SpringExtension.class)
@DataJpaTest

@ContextConfiguration(initializers = {SalesRepositoryTest.Initializer.class})
public class SalesRepositoryTest {  

    @Autowired
    private SalesRepository repository; 

因此,我可以看到针对 Web 端(@WebMvcTest)和数据库端(@DataJpaTest)的专用 spring 切片注释

但是,当我需要测试我的 @Service 注解的类时,我应该使用哪个 spring 切片? 我没有看到任何专门用于服务层的内容

我问的原因是我正在这样使用它: 注意(对存储库的调用是模拟的,因此基本上我的服务层单元测试是隔离的)

@ExtendWith(SpringExtension.class)
@SpringBootTest
class TieredClaimServiceTest {

    @Autowired
    private TieredClaimService tieredClaimService;  

    @MockBean
    private SalesRepository salesRepository;

然而问题是,当我运行这些单元测试时,会调用一些不必要的 jpa/hibernate 代码。

我该如何防止这种情况?

2019-11-29 | 21:04:17.293 | SpringContextShutdownHook | SpringContextShutdownHook调试| org.hibernate.SQL |删除表discount_tiers(如果存在) Hibernate:删除表discount_tiers(如果存在) 2019-11-29 | 21:04:17.293 | SpringContextShutdownHook | SpringContextShutdownHook调试| org.hibernate.SQL |删除表商品(如果存在) Hibernate:删除表商品(如果存在) 2019-11-29 | 21:04:17.293 | SpringContextShutdownHook | SpringContextShutdownHook调试| org.hibernate.SQL |删除表销售(如果存在) Hibernate:删除表销售(如果存在) 2019-11-29 | 21:04:17.293 | SpringContextShutdownHook | SpringContextShutdownHook调试| org.hibernate.SQL |删除表用户(如果存在) Hibernate:删除表用户(如果存在) 2019-11-29 | 21:04:17.309 | SpringContextShutdownHook | SpringContextShutdownHook调试| org.hibernate.SQL |如果存在 hibernate_sequence 则删除序列 Hibernate:如果存在 hibernate_sequence* 则删除序列

2019-11-29 | 21:04:17.309 | SpringContextShutdownHook | SpringContextShutdownHook调试| o.h.t.s.TypeConfiguration$范围 |从 SessionFactory [org.hibernate.internal.SessionFactoryImpl@17fddecd] 取消 TypeConfiguration [org.hibernate.type.spi.TypeConfiguration$Scope@89296ce] 的作用域

我想这些会出现在日志中,因为在我的 application.properties (在 /src/test/resources 下)我有这个:

spring.jpa.hibernate.ddl-auto=create-drop

但是,当我对存储库层进行单元测试时,我需要此配置,因此我无法删除或删除它

那么对于我的服务层有没有 spring 切片注释? 当我测试与数据库/存储库隔离的服务层(因为该层被模拟)时,如何避免发生 hibernate/jpa 调用或加载?

EDIT1:根据下面的答案,我想我没有提供服务类别的完整详细信息: 我尝试了以下操作,但由于又注入了一个服务类,我遇到了问题:( DiscountTierService 也被注入到 TieredClaimServiceImpl 中)

这是完整的示例:

@Service
public class TieredClaimServiceImpl implements TieredClaimService {

//@Autowired
private MerchRepository merchRepository;

//@Autowired
private SalesRepository salesRepository;

@Autowired
private DiscountTierService discountTierService;

private static final Logger LOGGER = LoggerFactory.getLogger(TieredClaimServiceImpl.class);

public TieredClaimServiceImpl() {       
}

@Autowired
public TieredClaimServiceImpl(MerchRepository merchRepository,SalesRepository salesRepository) {
    this.merchRepository = merchRepository;
    this.salesRepository = salesRepository;
}

@Override
//public List<? extends MerchSales>  calculateClaim(String code,LocalDate fromDate,LocalDate toDate) {
public List <TieredClaimDto>  calculateClaim(ClaimRequestDto claimRequestDto,String xAppCorelationId) throws SystemException {

这是修改后的测试类:

@ExtendWith(SpringExtension.class)
class TieredClaimServiceTest {

private TieredClaimService tieredClaimService;  


@MockBean
private SalesRepository salesRepository;

@MockBean   
private MerchRepository merchRepository;

@BeforeEach
void setUp() {
    tieredClaimService = new 
    TieredClaimServiceImpl(merchRepository,salesRepository);
}




//@Autowired
//private DiscountTierService discountTierService;
@ParameterizedTest
@ValueSource(strings = {"merch", "sales"})
@DisplayName("xyz ")
void tieredClaimPositiveScenarioWithinTier(String sourceType) throws Exception {

在实际的服务类中,我得到了注入,因为 DiscountTierService 没有被注入:

我在以下代码行中得到了 NPE:

@Override
public List <TieredClaimDto>  calculateClaim(ClaimRequestDto claimRequestDto,String xAppCorelationId) throws SystemException {


    /** get the discount tier config data **/
    **List<DiscountTierDto> discountTierList = discountTierService.get();**

对于您的服务层,您不需要使用/不需要弹簧片。 您只需使用 JUnit 测试您的 service.class 并使用 Mockito 模拟存储库,就像您在控制器中使用服务所做的那样。

如果您需要 Spring Context,您还可以使用 @RunWith(MockitoJUnitRunner.class) 或 @RunWith(SpringRunner.class) 注释您的测试类...

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

spring boot 使用哪个“切片”来测试服务组件 的相关文章

随机推荐

  • 使用 AsyncTask 进行服务

    我听说服务中存在异步任务并不好 真的有必要吗AsyncTask要不就onStartCommand 我想知道因为我有一个Service与AsyncTask由警报启动 并且它推出了Service不止一次 它应该只启动一次 难道是这个原因吗 ED
  • MySQL正则表达式:如何将字符串中的数字与\d匹配?

    我有一个专栏release date它以字符串格式存储日期 不是 DATETIME 格式 因为它们有时可以是任何其他字符串文字 我想根据给定的月份和年份查找任意日期的所有记录 尝试遵循但对我不起作用 gt Post find all con
  • 如何在 Gremlin 中查找公共顶点数并对结果进行排序?

    我的架构有两种类型的节点 node1 学生 id为主键 节点2 技能 技能名称为主键 他们之间的关系是HAS SKILL 我的用例 对于给定的学生 Id 我需要获取技能最匹配的相似用户 技能计数和常用技能列表 我尝试过的查询 g V has
  • 自定义 XML 文件比较

    我看过很多关于 XML 比较的帖子 但我看过的没有一个能解决我的问题 我们有一些 XML 格式的文本文档 产品描述 带有标题和段落 正在更新 即版本化 我的任务是制作变更摘要 也就是说 我们想要获取两个连续的文件并生成第三个 标题结构 大纲
  • 如何清除 (WPF) DataGrid 中的单元格(使其获取 NULL 值)?

    我们有一个列绑定到一个可为空的 SQL 整数值 当用户尝试 清除 单元格时DataGrid 我们得到验证错误 无法转换 如何将其设置为空并将 空 值绑定到基础列 我已经用谷歌搜索了这个问题两天并找到了任何东西 我试图编辑我对 HCL 的评论
  • 使用base64编码图像的优点和缺点[关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 我正在考虑为我正在开发的网站使用 Base64 编码图像来优化加载时间 不管怎样 在开始之前 我想知道 这样做的优点和缺点是什么 目前 我没有看
  • Visual Studio 加载符号

    我正在研究一个冷聚变 http en wikipedia org wiki ColdFusion项目已经有一段时间了 Visual Studio 至少对我来说开始表现得很奇怪 我观察到 当我开始调试时 它构建了项目 开始部署 部署完成并开始
  • 如何按角色限制对 Spring Data REST 投影的访问?

    在使用 Spring Data JPA 和 Spring Data REST 的应用程序中 假设您有一个如下所示的实体类 Entity public class Person Id GeneratedValue private int id
  • Sphinx 的 .. include:: 指令和“重复标签”警告

    我正在尝试使用Sphinx http sphinx doc org s include 指示 http docutils sourceforge net docs ref rst directives html include将一个文件中的
  • org.neo4j.kernel.GraphDatabaseQueryService 无依赖满足接口

    我只是编写一个简单的程序 将 GTFS 文件上传到 Neo4j Spatial 我相信这是一些配置错误或 Neo4j spatial 库的一些问题 这就是为什么我没有上传我的代码 这是指定的非常基本的代码here https github
  • 动态加载具有某些其他 dll 依赖项的 .NET 程序集

    我想为我的应用程序创建一个插件引擎 但我有一个问题 如何加载对其他程序集有一定依赖的 Net 程序集 实际上是我的插件 例如我想加载A DLL and A DLL需要B dll or C dll等等来运行 这A dll有两种方法 例如A a
  • Chrome/Firefox 在后台发送两个 POST,间隔恰好 5 秒,仅调用一次来获取 Nodejs 8.0.0 服务器

    注意 这不是飞行前选项 也不是网站图标或其他类似内容 实际上是 2 个帖子 下面有一个屏幕截图可以更清楚地显示这一点 我的规格 版本 macOS 塞拉利昂版本 10 12 3 Chrome 版本 61 0 3128 0 官方版本 开发版 6
  • 过滤器的 Scala 集合类型

    假设您有一个 List 1 1 其类型为 List Any 这当然是正确的且符合预期 现在如果我像这样映射列表 scala gt List 1 1 map case x Int gt x case y String gt y toInt 结
  • 正确实现单链表 C++

    我有一份雇主名单 例如 节点 1 吉尔 Matt 乔 鲍勃 Matt 节点 2 Jeff James John 乔纳森 John Edward 节点 3 Matt Doe Ron 巴勃罗 Ron Chase Ron 蔡斯 路易 我试图让它到
  • 如何在 GraphQL 中处理多种类型的数组(例如:不同的内容块)?

    假设我有一个页面构建器字段 它引用许多不同类型的内容块 Video Quote 广告 etc 根据我的阅读 不鼓励在数组中包含多种类型 但是在这种情况下你还应该做什么呢 有没有办法在 GraphQL 中处理这个问题 有没有更好的方法来构建数
  • 我是否需要 getter 和 setter 以及额外的实体构造函数?

    我正在尝试在 Android 项目中使用 ORMLite 进行数据库持久化 从例子来看一切都很好 当我开始使用它时 我发现我并不完全理解它的要求和行为 假设我有一个名为 Bone 的课程 我想坚持下去 DatabaseTable table
  • 回到使用 ajax 的 PushState 条目

    我对以下情况有疑问 用户访问网站 用户点击使用history pushState的链接来更新url 通过ajax加载部分页面内容 使用jQuery 用户单击加载新页面的常规链接 用户点击返回返回到pushState条目 该页面现在仅显示通过
  • 无法在jspdf中加载多个图像

    我正在尝试加载动态生成的多个图像 我想将这些图像转换为 PDF 格式 HTML 代码如下
  • 无法在 auto_now = True 的情况下在表单上显示 DateField

    我有一个带有 auto now 的模型 并为更新和创建字段设置了 auto now add class HotelProfiles models Model fe result id models AutoField primary key
  • spring boot 使用哪个“切片”来测试服务组件

    我正在使用 spring boot 开发一个rest api 它由标准层组成 控制器 RestController 处理传入的http请求并公开api端点 然后是服务层 Service 最后是存储库层 Repository 我的问题是关于单