单测的思路

文章目录

  • 定义
  • 方法的单测
    • 几种生成工具的对比
    • 生成步骤
  • 接口的单测
  • 场景的单测
  • 参考

定义

  • 单元测试(Unit Testing)是一种软件开发中的测试方法,它的主要目的是确保软件中的最小可测试单元(通常是函数、方法或类)在被单独测试和验证时能够按照预期工作。尽管单元测试有很多优点,如提高代码质量、减少Bug、简化调试过程等,但它也存在一些缺点:
    • 增加开发时间:如要求覆盖率到80%甚至90%,或者入参几十个难以构造,单测时间占比可能超过30%。
    • 需要维护:随着代码的改变,特别是大规模的重构,单元测试也需要相应地更新和维护,增加开发的负担。
    • 无法发现对其他类的影响:单元测试主要关注单个单元的行为,无法发现与多个单元交互或整个系统相关的问题。
  • 所以部分公司会要求写接口维度、场景维度的单测,覆盖率在50-60%,甚至不强制要求覆盖率。

方法的单测

推荐用更智能的squaretest生成单测模板后,手工调整。

几种生成工具的对比

  • diffblue
    • 优点:
      • 与IntelliJ IDEA集成良好,使用方便。
      • 支持多种编程语言和框架。
    • 缺点:
      • 商用版本收费较高,对于个人用户或小型团队可能不太友好。
      • 在处理某些特定写法或框架时可能不够灵活。
  • squaretest
    • 优点:
      • 生成测试用例,自动覆盖部分if分支,减轻测试负担。
    • 缺点:
      • 只有30天的免费试用期,之后需要付费使用。事实上点掉remind后可以继续使用。
      • 没有社区版支持,对于开源项目或个人用户可能不太友好。
  • EvoSuite
    • 优点:
      • 作为Maven插件使用,方便集成到Java项目中。
      • 支持生成多样化的测试用例,有助于发现潜在的缺陷。
    • 缺点:
      • 社区支持相对较少,遇到问题时可能难以得到及时帮助。
      • 配置和使用可能相对复杂,需要一定的学习成本。
      • 在处理某些特定场景或框架时可能不够灵活或有效。
  • TestMe
    • 优点:
      • 简单易用,适合初学者或小型项目使用。
    • 缺点:
      • 需要手动填充输入参数和逻辑,自动化程度较低。
      • 生成的测试用例可能不够全面或深入,需要额外补充和完善。

生成步骤

  1. 安装插件
    在这里插入图片描述

  2. 引入依赖

    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><version>2.1.1.RELEASE</version></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>5.8.2</version></dependency>
  1. 编写业务代码
@Service
public class TestServiceImpl implements TestService {@Resourceprivate TestRepository testRepository;@Resourceprivate TestThird testThird;@Overridepublic void start(InputDTO inputDTO) {InputEntity entity = testRepository.select(inputDTO.getId());if (entity == null) {testRepository.insert(entity = new InputEntity());}testThird.callThird(entity);}
}
  1. 生成单测
    在这里插入图片描述在这里插入图片描述
  2. 单测生成结果
/*** squaretest*/
class TestServiceImplTest {@Mockprivate TestRepository mockTestRepository;@Mockprivate TestThird mockTestThird;@InjectMocksprivate TestServiceImpl testServiceImplUnderTest;@BeforeEachvoid setUp() {initMocks(this);}@Testvoid testStart() {// Setupfinal InputDTO inputDTO = new InputDTO();inputDTO.setName("name");inputDTO.setId(0);final InputDetail inputDetail = new InputDetail();inputDetail.setName("name");inputDTO.setInputDetail(inputDetail);// Configure TestRepository.select(...).final InputEntity inputEntity = new InputEntity();inputEntity.setId(0);inputEntity.setName("name");when(mockTestRepository.select(0)).thenReturn(inputEntity);when(mockTestRepository.insert(any(InputEntity.class))).thenReturn(0);// Run the testtestServiceImplUnderTest.start(inputDTO);// Verify the resultsverify(mockTestRepository).insert(any(InputEntity.class));verify(mockTestThird).callThird(any(InputEntity.class));}
}
/*** testme*/
class TestServiceImplTestTestMe {@MockTestRepository testRepository;@MockTestThird testThird;@InjectMocksTestServiceImpl testServiceImpl;@BeforeEachvoid setUp() {MockitoAnnotations.initMocks(this);}@Testvoid testStart() {when(testRepository.select(anyInt())).thenReturn(new InputEntity());when(testRepository.insert(any())).thenReturn(Integer.valueOf(0));testServiceImpl.start(new InputDTO());}
}

接口的单测

mock外部依赖,启动容器,调用接口

  1. 编写外部依赖的mock类
@Service
public class TestThirdImpl implements TestThird {@Overridepublic void callThird(InputEntity entity) {System.out.println("TestThirdImpl callThird");}
}
//mock
public class TestThirdMockImpl implements TestThird {public void callThird(InputEntity entity) {System.out.println("TestThirdMockImpl callThird");}
}
  1. 替换容器中的bean,mock外部依赖
@Configuration
public class MockConfig {@Beanpublic BeanDefinitionRegistryPostProcessor beanDefinitionRegistryPostProcessor() {return new BeanDefinitionRegistryPostProcessor() {@Overridepublic void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {//移除依赖的beanregistry.removeBeanDefinition("testThirdImpl");//获取Mockbean的定义BeanDefinition beanDe = BeanDefinitionBuilder.rootBeanDefinition(TestThirdMockImpl.class).getBeanDefinition();//注册mockbeanregistry.registerBeanDefinition("testThirdImpl", beanDe);}@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {}};}
}
  1. test模块中启动容器,并调用入口方法
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = TestApplication.class)
public class TestApplicationTest {@Resourceprivate TestService testService;@Testpublic void start() {testService.start(new InputDTO());}}

场景的单测

将接口单测组合

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = TestApplication.class)
public class TestApplicationTest {@Resourceprivate TestService testService;@Testpublic void start() {testService.start(new InputDTO());testService.end(new InputDTO());}}

参考

  • 告别加班/解放双手提高单测覆盖率之Java 自动生成单测代码神器推荐
  • JUnit 5 User Guide
  • 关于testNG和JUnit的对比
  • JUnit 5 单元测试教程
  • 单元测试自动生成工具EvoSuite的简单使用
  • 使用BeanDefinitionRegistryPostProcessor动态注入BeanDefinition

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/468172.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Netty Review - ServerBootstrap源码解析

文章目录 概述源码分析小结 概述 ServerBootstrap bootstrap new ServerBootstrap();bootstrap.group(bossGroup, workerGroup).channel(NioServerSocketChannel.class).option(ChannelOption.SO_BACKLOG, 1024).childHandler(new ChannelInitializer<SocketChannel>() …

全球夜间灯光(1992-2021 年)更新(1km空间分辨率)

统一的全球夜间灯光&#xff08;1992-2021 年&#xff09; 在这项研究中&#xff0c;作者通过协调来自 DMSP 数据的相互校准的 NTL 观测数据和来自 VIIRS 数据的模拟 DMSP 类 NTL 观测数据&#xff0c;生成了全球尺度的综合一致的 NTL 数据集。生成的全球 DMSP NTL 时间序列数据…

【运维测试】移动测试自动化知识总结第1篇:移动端测试介绍(md文档已分享)

本系列文章md笔记&#xff08;已分享&#xff09;主要讨论移动测试相关知识。主要知识点包括&#xff1a;移动测试分类及android环境搭建&#xff0c;adb常用命令&#xff0c;appium环境搭建及使用&#xff0c;pytest框架学习&#xff0c;PO模式&#xff0c;数据驱动&#xff0…

【十六】【C++】stack的常见用法和练习

stack的常见用法 C标准库中的stack是一种容器适配器&#xff0c;它提供了后进先出&#xff08;Last In First Out, LIFO&#xff09;的数据结构。stack使用一个底层容器进行封装&#xff0c;如deque、vector或list&#xff0c;但只允许从一端&#xff08;顶部&#xff09;进行…

Excel模板2:进度条甘特图

Excel模板2&#xff1a;进度条甘特图 ‍ 今天复刻B站up【名字叫麦兜的狗狗】的甘特图&#xff1a;还在买Excel模板吗&#xff1f;自己做漂亮简洁的甘特图吧&#xff01;_哔哩哔哩_bilibili 阿里网盘永久分享&#xff1a;https://www.alipan.com/s/cXhq1PNJfdm 当前效果&…

幻兽帕鲁Palworld专用服务器CPU内存配置怎么选择?

腾讯云幻兽帕鲁服务器配置怎么选&#xff1f;根据玩家数量选择CPU内存配置&#xff0c;4到8人选择4核16G、10到20人玩家选择8核32G、2到4人选择4核8G、32人选择16核64G配置&#xff0c;腾讯云百科txybk.com来详细说下腾讯云幻兽帕鲁专用服务器CPU内存带宽配置选择方法&#xff…

ClickHouse--04--数据库引擎、Log 系列表引擎、 Special 系列表引擎

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1.数据库引擎1.1 Ordinary 默认数据库引擎1.2 MySQL 数据库引擎MySQL 引擎语法字段类型的映射 2.ClickHouse 表引擎3.Log 系列表引擎几种 Log 表引擎的共性是&#…

分享87个CSS3特效,总有一款适合您

分享87个CSS3特效&#xff0c;总有一款适合您 87个CSS3特效下载链接&#xff1a;https://pan.baidu.com/s/1CAxe8nPBzXvH7Nr6B_U72Q?pwd8888 提取码&#xff1a;8888 Python采集代码下载链接&#xff1a;采集代码.zip - 蓝奏云 学习知识费力气&#xff0c;收集整理更不…

机械革命混合模式和独显直连互相切换

原文&#xff1a;https://blog.iyatt.com/?p13773 默认状态是混合输出&#xff0c;在任务管理器中可以看到两个 GPU&#xff0c;分别是核显和独显 从混合模式切换到独显直连可以通过机械革命电竞控制台&#xff08;重装过系统的需要去官网下载安装驱动&#xff09; 打开后…

如何流畅进入Github

前言 以下软件是免费的&#xff0c;放心用 一、进入右边的下载链接https://steampp.net/ 二、点击下载 三、点击接受并下载 四、随便选一个下载链接进行下载 五、软件安装好打开后&#xff0c;找到Github 六、点击全部启用 七、再点击左上角的一键加速 八、这个时候你再进Git…

向量搜索查询faiss、annoy

首先介绍annoy : 转发空间&#xff1a;https://download.csdn.net/blog/column/10872374/114665212 Annoy是高维空间求近似最近邻的一个开源库。 Annoy构建一棵二叉树&#xff0c;查询时间为O(logn)。 Annoy通过随机挑选两个点&#xff0c;并使用垂直于这个点的等距离超平面…

Unity下使用Sqlite

sqlite和access类似是文件形式的数据库&#xff0c;不需要安装任何服务&#xff0c;可以存储数据&#xff0c;使用起来还是挺方便的。 首先需要安装DLL 需要的DLL 我们找到下面两个文件放入Plugins目录 Mono.Data.Sqlite.dll System.Data.dll DLL文件位于Unity的安装目录下的…