单元测试说明

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

单元测试需要保证以下几点:

  1. 不依赖外部系统
  2. 单元测试足够“单元”,避免流程过长的测试逻辑
  3. 测试方法的数据操作不影响真实数据源的数据现状
  4. 每个测试方法都要有verify或者Assert的验证或断言的操作,否则都是无效的测试方式
  5. 一些依赖外部系统的调用,或不需要每次单元测试都执行的测试类或测试方法,及时使用@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单元测试相关推荐

  1. 基于Groovy的Spock单元测试框架入门指南

    文章目录 1. Spock Primer 基本概念 1.1 对比Junit 1.2 Imports 1.3 Specification测试类 1.4 Fields 属性 1.5 Fixture Met ...

  2. groovy 兼容 java,升级Groovy 1.7 - 2.1不兼容

    我正在从Groovy 1.76迁移到groovy 2.1并且在运行一些Java代码时出现问题 . 我在我的类路径上设置了java 7和Groovy 2.1 . Gradle正在运行,我的项目可以像以前 ...

  3. 高质量的单元测试 Spock单元测试框架详讲

    文章目录 方法篇 为什么需要单元测试 单元测试的定义 单元测试与其他测试的区别 单元测试的作用 关于单元测试的成本 如何写好单元测试 什么场景适合单元测试 单元测试的粒度 关于TDD TDD的三定律 ...

  4. Maven找不到要运行的JUnit测试

    我有一个Maven程序,它可以正常编译. 当我运行mvn test它不会运行任何测试(在TESTs标头下显示There are no tests to run. ). 我已经用一个非常简单的设置重新创 ...

  5. 对 Groovy 进行单元测试

    本教程一直都强调 Groovy 只是 Java 的一个变体.您已经看到可以用 Groovy 编写并使用标准的 Java 程序.为了最后一次证明这点,在结束本教程之前,我们将通过 JUnit 利用 Ja ...

  6. 怎么使用Groovy+Spock做单元测试?

    1. 背景 平时我们写代码,免不了要进行一些测试,如果没有使用单元测试,对于简单的程序,我们可以写一个main方法,调试查看指定的方法是否符合预期:对于一个服务系统,我们可以使用PostMan等工具来 ...

  7. 单元测试:基于Groovy的Spock框架

    1.简介 Spock 框架是一个基于groovy语法的测试框架,由于使用groovy,所以使用起来比 junit 更加灵活,测试用例的写法更加简单易懂,一目了然. 如果使用过junit,spock的则 ...

  8. groovy语言单元测试(spock)

    一.spock-groovy单元测试的五种情况 /**  * 单元测试  * given: mock单测中指定mock数据,模拟入参  * when: 触发行为,比如调用指定方法或函数  * then ...

  9. Groovy学习摘要

    为什么80%的码农都做不了架构师?>>>    首先感谢翻译<Groovy in Action>Part 1的吴翊,其次感谢Groovy之父James Strachan ...

最新文章

  1. oracle中计算某月的天数
  2. 电脑服务器怎么打开网页,电脑的iis服务器打开网页的方法
  3. SAP CRM, C4C和Hybris的后台作业
  4. 控件必须放在具有 runat=server 的窗体标记内错误的解决方法
  5. [java] JVM监控与调优
  6. YUM命令常见报错以及解决办法
  7. Eclipse常用快捷键【转】
  8. Python3 Tkinter 之 (1) 主窗口框架
  9. 什么是Joint Escalation Team?
  10. 2.nginx 配置
  11. DEMATEL算法程序
  12. Jtag接口定义及含义
  13. 【Python】实现B站MP4格式音频与视频合并,ffmpeg一个命令即可
  14. 好的提高代码质量的方法有哪些?
  15. 和风天气:免费天气接口,包含天气预报及空气质量等实用信息,使用简单方便(划重点:免费)
  16. 最新微信小程序获取音频时长与实时获取播放进度
  17. ROS+UR机械臂系列-1- 虚拟机及ROS安装
  18. 阿里巴巴十周年庆典流水账
  19. 更改keil主题颜色背景
  20. 2023免费PPT网站12个

热门文章

  1. Veeam BackupReplication简介
  2. 每天一个小题目——约德尔测试
  3. 关于google earth engine(GEE)的一些想法与大胆预测
  4. 《天龙八部2》2.30.1607 人物与宝宝基址,是最新的
  5. 希伯特19+9步行者1-0热火 乔治24+7詹皇25+10+5
  6. 谷歌浏览器崩溃的解决方案
  7. 公司增值税太高了怎么办?除了此法解决就别无他法了吗?
  8. 一文详解VarScan肿瘤体细胞突变检测的的安装和实践
  9. Docker实践2:用Docker搭建hg-server
  10. 2020最新版Selenium异常集锦