Spock 1.2 –轻松进行集成测试中的Spring Bean模拟

探索如何使用Spock 1.2将Spock的模拟和间谍自动注入到Spring上下文中。

Spock中的存根/模拟/间谍(及其生命周期)一直与Spock Specification类紧密结合。 只能在测试类中创建它们。 因此,使用共享的预定义模拟(在单元测试和集成测试中)是有问题的。

这种情况在Spock 1.1中有所改善,但只有在基于Spring的集成测试中使用Spock模拟子系统的全新Spock 1.2(撰写本文时为1.2-RC1)时,与在Spring中对Mockito模拟使用@SpringMock一样容易开机 让我们检查一下。

顺便说一句,除Spock 1.2-RC1之外,为了更前沿,我将使用Spring Boot 2.1.0.M2,Spring 5.1.0.RC2和Groovy 2.5.2(但所有功能都应在Spring的稳定版本中使用(引导)和Groovy 2.4)。

斯波克

还有一件事。 为了简单起见,在本文中,我将使用术语“模拟”来指代存根和间谍。 它们的行为有所不同 ,但是在Spock测试中将其注入Spring上下文的范围通常并不重要。

Spock 1.1 –手动方式

多亏了LeonardBrünings的工作,Spock中的模拟才脱离了Specification类。 最终可以在外部创建它们,然后将其附加到正在运行的测试中。 这是在Spring(或任何其他)上下文中使用Spock模拟的基础。

在此示例代码中,我们具有ShipDatabase类,该类使用OwnShipIndexEnemyShipIndex (当然是由构造函数注入的:))来返回有关所有与名称匹配的已知船只的汇总信息。

//@ContextConfiguration just for simplification, @(Test)Configuration is usually more convenient for Spring Boot tests
//Real beans can exist in the context or not
@ContextConfiguration(classes = [ShipDatabase, TestConfig/*, OwnShipIndex, EnemyShipIndex*/])
class ShipDatabase11ITSpec extends Specification {private static final String ENTERPRISE_D = "USS Enterprise (NCC-1701-D)"private static final String BORTAS_ENTERA = "IKS Bortas Entera"@Autowiredprivate OwnShipIndex ownShipIndexMock@Autowiredprivate EnemyShipIndex enemyShipIndexMock@Autowiredprivate ShipDatabase shipDatabasedef "should find ship in both indexes"() {given:ownShipIndexMock.findByName("Enter") >> [ENTERPRISE_D]enemyShipIndexMock.findByName("Enter") >> [BORTAS_ENTERA]when:List<String> foundShips = shipDatabase.findByName("Enter")then:foundShips == [ENTERPRISE_D, BORTAS_ENTERA]}static class TestConfig {private DetachedMockFactory detachedMockFactory = new DetachedMockFactory()@Bean@Primary    //if needed, beware of consequencesOwnShipIndex ownShipIndexStub() {return detachedMockFactory.Stub(OwnShipIndex)}@Bean@Primary    //if needed, beware of consequencesEnemyShipIndex enemyShipIndexStub() {return detachedMockFactory.Stub(EnemyShipIndex)}}
}

这些模拟是在单独的类中(在Specification之外)创建的,因此必须使用DetachedMockFactory (或使用SpockMockFactoryBean )。 这些模拟必须附加(和分离)到测试实例( Specification实例),但是它由spock-spring模块(从1.1版本开始)自动处理。 对于从外部创建的通用MockUtil.attachMock() ,还需要使用MockUtil.attachMock()mockUtil.detachMock()使其起作用。

结果,可以在Spring上下文中创建和使用模拟,但是它不是很方便,也不常用。

Spock 1.2 –一流的支持

Spring Boot 1.4通过(Mockito的)模拟为集成测试带来了新的质量。 它利用了最初于2012年在Springockito中提出的想法(当时Spring配置主要是用XML编写的:))将模拟(或间谍)自动注入到Spring(引导)上下文中。 Spring Boot团队扩展了这个想法,并且由于有了它作为内部支持的功能(通常),因此只需在测试中添加一个或两个注释即可可靠地工作。

Spock 1.2中内置了类似的基于注释的机制。

//@ContextConfiguration just for simplification, @(Test)Configuration is usually more convenient for Spring Boot tests
//Real beans can exist in the context or not
@ContextConfiguration(classes = [ShipDatabase/*, OwnShipIndex, EnemyShipIndex*/])
class ShipDatabaseITSpec extends Specification {private static final String ENTERPRISE_D = "USS Enterprise (NCC-1701-D)"private static final String BORTAS_ENTERA = "IKS Bortas Entera"@SpringBeanprivate OwnShipIndex ownShipIndexMock = Stub()  //could be Mock() if needed@SpringBeanprivate EnemyShipIndex enemyShipIndexMock = Stub()@Autowiredprivate ShipDatabase shipDatabasedef "should find ship in both indexes"() {given:ownShipIndexMock.findByName("Enter") >> [ENTERPRISE_D]enemyShipIndexMock.findByName("Enter") >> [BORTAS_ENTERA]when:List<String> foundShips = shipDatabase.findByName("Enter")then:foundShips == [ENTERPRISE_D, BORTAS_ENTERA]}
}

没有太多要添加的内容。 @SpringBean指示Spock将模拟注入到Spring上下文中。 类似地, @SpringSpy用间谍包装真实的bean。 在@SpringBean的情况下,需要初始化一个字段以让Spock知道我们打算使用存根还是模拟。

此外,还有一个更通用的批注@StubBeans ,用存根替换所有已定义的bean。 但是,我计划在另一篇博客文章中单独介绍它。

局限性

对于那些希望在本文演讲后立即在您的Spock测试中将所有Mockito的模拟重写为Spock的模拟的人来说,这是一个警告。 Spock的模拟物-由于其性质和与Specification关系-具有某些局限性。 幕后的实现创建了一个代理,该代理被注入到Spring上下文中(可能)替换真实的bean(存根/模拟)或包装它们(间谍)。 该代理在特定测试(规范)类中的所有测试之间共享。 实际上,在Spring能够缓存上下文的情况下,它也可以跨越具有相同bean / mock声明的其他测试(与Mockito的模拟或通常的Spring集成测试类似的情况)。

但是,真正重要的是,代理在执行之前即被附加到测试,并在执行之后被分离。 因此,实际上,每个测试都有其自己的模拟实例(不能应用于@Shared字段),例如将来自不同测试的交互分组并一起验证它们是有问题的(通常是很明智的,但可能会导致某些情况)复制)。 但是,使用setup块(或在线存根)可以共享存根和交互期望。

摘要

Spock 1.2最终带来了轻松的Spock存根/模拟/间谍支持,以便在Spring上下文中使用它们,这与Spring Boot中为Mockito提供的存根相当。 将spock-spring模块添加到项目(运行时)依赖项就足够了。 尽管有一些限制,但在Spock(集成)测试中将本机Spock的模拟子系统与外部模拟框架(例如Mockito)混合使用,却少了一点。 不错的是,它也应该在普通的Spring Framework测试(不仅是Spring Boot测试)中工作。 Guice已实现了相同的功能(但我尚未对其进行测试)。

此外,Spock 1.2还带来了其他一些变化,包括对Java 9+的更好支持,值得在您的测试套件中进行尝试(当然,请报告任何可能发现的回归bug :)。

还有一个好消息。 除了使Spock 1.2成为可能的伦纳德的工作以及大量的错误报告者和PR贡献者之外,最近以来,还有其他一些提交者正在致力于使Spock变得更好。 您可能从其他一些流行的FOSS项目中了解了其中一些。 而且,Spock 1.2 (初步)计划成为基于JUnit 4的最后一个版本,而下一个稳定的Spock版本可能是2.0,这是利用JUnit 5及其(以及其他)并行运行测试的本机能力。

这些示例是使用Spock 1.2-RC1编写的。 一旦发布,它将更新为1.2-final。 源代码可从GitHub获得。

翻译自: https://www.javacodegeeks.com/2018/09/spock-spring-beans-mocking-integration.html

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

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

相关文章

geteditor p 取消自动_2020百度网盘超级会员怎么取消自动续费?

首先我们打开百度网盘&#xff0c;开通超级会员以后&#xff0c;可以看到个人中心有一个管理自动续费的&#xff0c;点击打开。2然后可以看到自己开通的界面旁边显示的有一个取消按钮。3点击取消以后&#xff0c;会提示我们自动续费享受的有优惠&#xff0c;我们继续点击确认取…

分布式机器学习_229页,CMU博士张昊毕业论文公布,探索机器学习并行化的奥秘...

CMU 机器人研究所张昊&#xff08;Hao Zhang&#xff09;博士论文新鲜出炉&#xff0c;主要围绕着机器学习并行化的自适应、可组合与自动化问题展开。机器之心报道&#xff0c;机器之心编辑部。随着近年来&#xff0c;机器学习领域的创新不断加速&#xff0c;SysML 的研究者已经…

利用Excel或LibreOffice的业务输入进行单元测试约束

业务专家向我们&#xff08;开发人员&#xff09;解释业务限制。 但是&#xff0c;如何确保我们正确理解它们呢&#xff1f; 或更糟糕的是&#xff0c;一旦约束条件正式化&#xff0c;我们如何测试他们之间是否同意&#xff1f; 好吧&#xff0c;有一种很棒的方法可以做到这一…

矩阵连乘 动态规划_Java动态规划

1. 介绍动态规划典型的被用于优化递归算法&#xff0c;因为它们倾向于以指数的方式进行扩展。动态规划主要思想是将复杂问题(带有许多递归调用)分解为更小的子问题&#xff0c;然后将它们保存到内存中&#xff0c;这样我们就不必在每次使用它们时重新计算它们。要理解动态规划的…

分布式光伏补贴_光伏发电上网电价政策综述

原标题&#xff1a;光伏发电上网电价政策综述近些年&#xff0c;光伏发电上网电价相关政策不断推陈出新&#xff0c;在推进平价上网的同时&#xff0c;也积极对接了电力市场建设需要。本文梳理了光伏发电上网电价及补贴标准有关政策&#xff0c;供参考使用&#xff1a;1.普通光…

单片机float数发给上位机_上位机倒计时器

1. 设置窗口在VS2019新建一个Windows窗体应用(.NET Framework)项目&#xff0c;新建之后出现一个可视化页面(From1.cs[设计])设置窗口。在左侧的工具箱里面拉拽控件到操作面板上&#xff0c;按照自己的喜好摆放位置和调大小。这里要注意的是用到的分别是什么控件&#xff1a;文…

土地利用覆被变化的概念_欠压实概念极其荒谬

●李传亮地表疏松的沉积物&#xff0c;孔隙度极高&#xff0c;有时可高达80%以上&#xff0c;但随着埋藏深度的加大&#xff0c;在上覆压力的作用下&#xff0c;其排列方式不断由松散排列趋于致密排列&#xff0c;同时伴随有孔隙度的大幅度减小&#xff0c;此即岩石的压实阶段&…

java足球游戏毕业设计,java毕业设计_springboot框架的校园足球管理平台

今天介绍一个java毕设题目, 题目内容为springboot框架的校园足球管理平台, 是一个采用b/s结构的javaweb项目, 采用java语言编写开发工具eclipse, 项目框架jspspringbootmybatis, 校园足球管理平台的信息存储于mysql中, 并基于mybatis进行了orm封装, 该校园足球管理平台系统通过…

Java 11功能– Java飞行记录器

在本文中&#xff0c;我们将看到如何利用Java Flight Recorder功能作为Java 11的一部分。之前&#xff0c;它是商业功能之一。 但是&#xff0c;对于带有JEP 328的 Java 11&#xff0c;它是开源的。 Java Flight Recorder将OS和JVM事件记录到一个文件中&#xff0c;可以使用Jav…

qstandarditemmodel 重写data函数后无法实现拖拽_实现类似百度网盘上传的功能

今天写到了上传文件部分&#xff0c;记录一下。前端使用了dropzone.js(用于实现文件上传的JS库)&#xff0c;并对此文件进行了细微修改。说一下思路吧&#xff1a;首先界面长这样&#xff1a;点击上传文件&#xff0c;需要弹出一个对话框&#xff0c;对话框中有支持拖拽文件的文…

逻辑斯蒂回归_逻辑斯蒂回归详细解析 | 统计学习方法学习笔记 | 数据分析 | 机器学习...

本文包括&#xff1a;重要概念逻辑斯蒂回归和线性回归二项逻辑斯谛回归模型逻辑斯蒂回顾与几率模型参数估计多项逻辑斯谛回归其它有关数据分析&#xff0c;机器学习的文章及社群1.重要概念&#xff1a;在正式介绍逻辑斯蒂回归模型之前&#xff0c;需要先对一些基本概念有所了解…

交通流预测 | Matlab基于KNN-BiLSTM的交通流预测(对比SVR、LSTM、GRU、KNN-LSTM)

目录 预测效果基本介绍程序设计参考资料 预测效果 基本介绍 交通流预测 | Matlab基于KNN-BiLSTM的交通流预测&#xff08;对比SVR、LSTM、GRU、KNN-LSTM&#xff09; 程序设计 完整程序和数据获取方式&#xff1a;私信博主回复Matlab基于KNN-BiLSTM的交通流预测&#xff08;对…

JMetro“ Metro”选项卡,Java的TreeView和ContextMenu(JavaFX)

我刚刚发布了JMetro的新更新&#xff0c;将版本升级到3.3.0。 在此更新中&#xff0c;您将找到&#xff1a; 新的TreeView Fluent设计系统&#xff08;Metro&#xff09;启发风格&#xff1b; 新的Tabs和TabPane FDS启发风格&#xff1b; 新的上下文菜单采用深色FDS启发的样…

数据挖掘原理与算法_技术分享|大数据挖掘算法之FPGrowth算法

程一舰数据技术处我们常说我们生活在信息时代&#xff0c;实际上&#xff0c;我们更多的还是生活在数据时代。因为从过去到现在累积了大量的数据&#xff0c;对数据的挖掘和分析也仅是从最近几年大数据和人工智能技术的发展而兴起。我们对现有数据价值的利用还远低于数据本身拥…

neo4j数据浏览器_Neo4j:在Neo4j浏览器的帮助下探索新数据集

neo4j数据浏览器在查看新的Neo4j数据库时&#xff0c;我发现遇到的一件困难就是确定其中包含的数据的结构。 我习惯于关系数据库&#xff0c;在该数据库中您可以轻松获取表列表和外键&#xff0c;以便您将它们相互连接。 传统上&#xff0c;使用Neo4j时很难做到这一点&#x…

mfc中怎么集成文件_怎么把几个pdf合并并打印在一份文件中?

a为什么我们要把pdf文件合并呢&#xff1f;当然我们要知道什么是pdf文件才能进行更多的操作&#xff0c;Pdf是我们许多人都会用到的一种存储文件的格式&#xff0c;它的内容基本是以图像的形式表现&#xff0c;所以我们在播放和打印的时候可以不用担心出现格式错乱的问题。PDF格…

php中日期选择代码,实现JS日期时间选择器

这次给大家带来实现JS日期时间选择器&#xff0c;实现JS日期时间选择器的注意事项有哪些&#xff0c;下面就是实战案例&#xff0c;一起来看一下。flatpickr 是一个轻量级、注重精益、由 UX 驱动和可扩展的 JavaScript 日期时间选择器。下载 演示 GitHubflatpickr 不依赖于任何…

php steam 第三方登录,Steam第三方登录

Steam第三方登录Laravel PHP7.3前端登录界面if(isset($steamprofile))window.οnlοadfunction(){var steamprofile {!!$steamprofile!!};var steamid {{$steamid}};if(steamid){$.post(/ajax/SocilaAuthLogin,{data:{userdata:steamprofile,type:steamLogin},},function(dat…

setitimer 创建两个定时器_UE4 Timer(定时器)相关源码分析

前言文章属于旧有文章搬运, 之前在csdn上面2019.11.6修改Timer是定时器, 用途:延时执行事件周期性执行事件参考官方文档Using TimersTimer可以...Timer能...Timer...... 编不下去了, 自己百度谷歌吧(手动狗头)TimerManagerTimer的管理类是FTimerManager, 是一个全局的Timer管理…

is array php,PHP 源码 — is_array 函数源码分析

php 中的 is_arrayphp 中的 is_array&#xff0c;它的签名是 is_array ( mixed $var ) : bool实现的源码在\ext\standard\type.c中可以找到PHP_FUNCTION(is_array)所处的位置&#xff0c;大概位于 273 行。在 PHP 中&#xff0c;这个系列的函数&#xff0c;是由很多个&#xff…