Groovy单元测试
单元测试说明
spock是基于groovy的测试框架,spock本身集成了Mockito+junit的功能,并且可以springboot-test结合启动容器测试。静态方法和私有方法仍需要使用PowerMock进行功能增强。
第一次使用推荐先看一下demo代码再看官方文档。
demo代码:可参考金融网关 CiticLoanApplyMsgConvertServiceImplTest(基础用法) 和 CiticbankLoanApplyServiceImplTest(Data Table 例子)
官方学习文档:http://spockframework.org/spock/docs/1.3/all_in_one.html
单元测试需要保证以下几点:
- 不依赖外部系统
- 单元测试足够“单元”,避免流程过长的测试逻辑
- 测试方法的数据操作不影响真实数据源的数据现状
- 每个测试方法都要有verify或者Assert的验证或断言的操作,否则都是无效的测试方式
- 一些依赖外部系统的调用,或不需要每次单元测试都执行的测试类或测试方法,及时使用
@Ignore
,避免mvn test时执行单元测试异常
基础语法
段落
spock单测方法是场景化测试,将单元测试分成了 [given->]when->then[->where] 或者 [given->]expect->where 段落,
每一个段落都有固定的作用
given: 准备数据阶段,可以以没有
when: 一般放置各种mock和测试方法调用,所以spock要求这个段落必须有(或者用expect)
then: 用于写断言的区域,spock要求必须有
expect: 可以理解为when + then的集合,需要固定跟 where搭配使用
where: 变量填充区。例如我们需要测试入参不同走不同逻辑的测试,junit需要写多个测试用例和mock。spock允许将这部分以数据表格集成到同一个用例,
每行代表一个测试场景,每一列代表一个变量
//@Subject是定义一个主题,目前没什么用处 @Subject(CiticLoanApplyMsgConvertServiceImpl.class) class CiticLoanApplyMsgConvertServiceImplSpockTest extends SpockBaseRunner { def init() {//等于junit @before}//spock默认遇到不通过的测试场景就不跑后续单测,@Unroll代表不中断@Unroll def "方法名称,建议直接使用中文"() {given: //准备数据阶段,没有可写null,或可以不写when: //这里写各种mock方法的返回等和调用需要单测的目标方法,没有可写nullnullthen://then用于编写断言,判断相等可以直接用 ==loanApplyRequest.data.applyAmt == 1004.00 and://断言分段编写用and连接def contract = loanApplyRequest.data.contractInfoList[0]contract.billCode == '60000144202004020128P'} }
启动模式
集成springboot-test 测试类继承 SpockBaseRunner,使用这种模式初始化方法为 init() 类似@Before(SpockBaseRunner封装了一下原生的setup())
这种模式下默认会为单测开启数据库事务,单测执行完后自动回滚事务
Specification 纯粹mock的形式类似纯junit + mockito,使用这种模式初始化方法为 setup() 类似junit @Before
Mock
mock一个对象例子如下
def serviceAObject = new ServiceA( property1: Mock(ServiceB)//多重mockproperty2: Mock(new ServiceC(cProperty1: Mock(ServiceD))) )
需要注意的是如果使用SpockBaseRunner 启动,默认容器就会注入所有依赖的bean,所以这时如果需要局部Mock某些属性,需要主动
在原来的Service上暴露对应属性set方法,然后再mock,可以参考 CiticbankLoanApplyServiceImplTest 中 Mock sellSendFileService
class CiticbankLoanApplyServiceImplTest extends SpockBaseRunner { ...def sellSendFileService = Mock(SellSendFileService)@Overridedef init() {...citicbankLoanApplyService.sellSendFileService = sellSendFileService} }@Setter //方便单元测试局部mock注入 @Service public class CiticbankLoanApplyServiceImpl implements SellLoanApplyService @Autowired@Qualifier("citicbankSellSendFileServiceImpl")private SellSendFileService sellSendFileService; }
mock 方法的返回值
citicbankHttpServerTemplate.packageRequest(*_) >> response _指代入参,类似Mockit的any(),*_标识任意个参数
赋值
变量 << 值 变量 << [数组] 变量 << new 对象(property1: value1, property2: value2)
断言
断言值相等 loanApplyRequest.data.applyAmt == 1004.00 其他场景可以转化为类似 表达式 == true 代表方法必须执行一次 1 * sellSendFileService.uploadAndSendFiles(*_) 代表方法至少行一次 (1.._) * sellSendFileService.uploadAndSendFiles(*_) 代表方法执行2~5次 (2..5) * sellSendFileService.uploadAndSendFiles(*_)
多行数据比较(CiticLoanApplyMsgConvertServiceImplSpockTest)
假设方法正常运行应该保存了4行数据,需要验证实际入库行数是否4行,各行的列值是否正确
... when: citicLoanApplyMsgConvertService.saveFileList(transNo, loanApplyRequest.data) ... List fileInfoList = sellFileInfoMapper.selectList(queryWrapper) then: fileInfoList.businessTransNo == [transNo, transNo, transNo, transNo] fileInfoList.fileCode == ['QT20200407000002179', 'QT20200402000001406', 'FM20200407112812', 'FM20200402117504']
一个单测多个用例(data table)使用(CiticbankLoanApplyServiceImplTest)
spock 运行 when和then 的表达式带有变量,具体的变量在运行时通过 where段落提供的数据填充,
例如以下代码提供了where 3个测试用例,每个用例对应where 里面的一行数据,复杂的变量(response)可以通过数组的方式单独赋值余列表方式等效:
... when: citicbankHttpServerTemplate.packageRequest(*_) >> response ... then: uploadFileCount * sellSendFileService.uploadAndSendFiles(*_) sellApply.getSellState() == sellState where: response << [ new Response(//模拟成功 code: CommonConstants.ResponseCode.SUCCESS ), new Response(//模拟前置接口失败 code: CommonConstants.ResponseCode.FRONT_FAILURE ), new Response(//模拟中信主动返回失败 code: CommonConstants.ResponseCode.FAILURE, data: new Response() )] sellState | uploadFileCount Constants.SellState.INIT.getState() | 1 Constants.SellState.INIT.getState() | 1 Constants.SellState.FAIL.getState() | 0
@WebAppConfiguration
@SpringBootTest
class SpockBaseRunner extends Specification {@AutowiredDataSourceTransactionManager dataSourceTransactionManager@AutowiredTransactionDefinition transactionDefinitionTransactionStatus transactionStatusdef setup() {transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);init()}def init() {}def cleanup() {dataSourceTransactionManager.rollback(transactionStatus)clean()}def clean() {}
}
Groovy单元测试相关推荐
- 基于Groovy的Spock单元测试框架入门指南
文章目录 1. Spock Primer 基本概念 1.1 对比Junit 1.2 Imports 1.3 Specification测试类 1.4 Fields 属性 1.5 Fixture Met ...
- groovy 兼容 java,升级Groovy 1.7 - 2.1不兼容
我正在从Groovy 1.76迁移到groovy 2.1并且在运行一些Java代码时出现问题 . 我在我的类路径上设置了java 7和Groovy 2.1 . Gradle正在运行,我的项目可以像以前 ...
- 高质量的单元测试 Spock单元测试框架详讲
文章目录 方法篇 为什么需要单元测试 单元测试的定义 单元测试与其他测试的区别 单元测试的作用 关于单元测试的成本 如何写好单元测试 什么场景适合单元测试 单元测试的粒度 关于TDD TDD的三定律 ...
- Maven找不到要运行的JUnit测试
我有一个Maven程序,它可以正常编译. 当我运行mvn test它不会运行任何测试(在TESTs标头下显示There are no tests to run. ). 我已经用一个非常简单的设置重新创 ...
- 对 Groovy 进行单元测试
本教程一直都强调 Groovy 只是 Java 的一个变体.您已经看到可以用 Groovy 编写并使用标准的 Java 程序.为了最后一次证明这点,在结束本教程之前,我们将通过 JUnit 利用 Ja ...
- 怎么使用Groovy+Spock做单元测试?
1. 背景 平时我们写代码,免不了要进行一些测试,如果没有使用单元测试,对于简单的程序,我们可以写一个main方法,调试查看指定的方法是否符合预期:对于一个服务系统,我们可以使用PostMan等工具来 ...
- 单元测试:基于Groovy的Spock框架
1.简介 Spock 框架是一个基于groovy语法的测试框架,由于使用groovy,所以使用起来比 junit 更加灵活,测试用例的写法更加简单易懂,一目了然. 如果使用过junit,spock的则 ...
- groovy语言单元测试(spock)
一.spock-groovy单元测试的五种情况 /** * 单元测试 * given: mock单测中指定mock数据,模拟入参 * when: 触发行为,比如调用指定方法或函数 * then ...
- Groovy学习摘要
为什么80%的码农都做不了架构师?>>> 首先感谢翻译<Groovy in Action>Part 1的吴翊,其次感谢Groovy之父James Strachan ...
最新文章
- oracle中计算某月的天数
- 电脑服务器怎么打开网页,电脑的iis服务器打开网页的方法
- SAP CRM, C4C和Hybris的后台作业
- 控件必须放在具有 runat=server 的窗体标记内错误的解决方法
- [java] JVM监控与调优
- YUM命令常见报错以及解决办法
- Eclipse常用快捷键【转】
- Python3 Tkinter 之 (1) 主窗口框架
- 什么是Joint Escalation Team?
- 2.nginx 配置
- DEMATEL算法程序
- Jtag接口定义及含义
- 【Python】实现B站MP4格式音频与视频合并,ffmpeg一个命令即可
- 好的提高代码质量的方法有哪些?
- 和风天气:免费天气接口,包含天气预报及空气质量等实用信息,使用简单方便(划重点:免费)
- 最新微信小程序获取音频时长与实时获取播放进度
- ROS+UR机械臂系列-1- 虚拟机及ROS安装
- 阿里巴巴十周年庆典流水账
- 更改keil主题颜色背景
- 2023免费PPT网站12个
热门文章
- Veeam BackupReplication简介
- 每天一个小题目——约德尔测试
- 关于google earth engine(GEE)的一些想法与大胆预测
- 《天龙八部2》2.30.1607 人物与宝宝基址,是最新的
- 希伯特19+9步行者1-0热火 乔治24+7詹皇25+10+5
- 谷歌浏览器崩溃的解决方案
- 公司增值税太高了怎么办?除了此法解决就别无他法了吗?
- 一文详解VarScan肿瘤体细胞突变检测的的安装和实践
- Docker实践2:用Docker搭建hg-server
- 2020最新版Selenium异常集锦