stub_AccuREST Stub Runner发布

stub

最近发布时间不错! 我在Too Much Coding博客上的博客更多是关于发布,然后是关于任何具体主题;)

在作为Brixton RC1的一部分发布Spring Cloud Sleuth之后,我们刚刚发布了AccuREST 1.0.4版本。 我们修复了一些错误,但引入了一些重要功能,包括:

  • Maven插件支持
  • Stub Runner功能

这篇文章将更深入地介绍后者。

介绍

我已经对名为Micro-Infra-Spring的库进行了很多讨论,在其中我介绍了如何从Stub Runner功能中受益。 自从我离开拥有该存储库的公司以来,几乎根本没有维护该项目。 很长一段时间以来,任何开发工作都是我自己完成的,实际上,我是大多数Stub Runner代码的作者。 由于上述原因以及Stub Runner与AccuREST的stub生成功能紧密结合的事实,我决定将其迁移到AccuREST的存储库。

AccuREST回顾

Stub Runner与AccuREST的概念紧密结合。 有关AccuREST的更多信息,您可以检查我的博客条目或在Github上检查AccuREST项目 。 如果您不知道那是什么,我会尽力快速回顾一下。

AccuREST是消费者驱动的合同验证器,您可以在其中通过Groovy DSL定义API的合同。 从该DSL,在服务器端,将创建测试以检查您的合同是否说实话。 从Stub Runner的角度来看,更有趣的是客户端。 对于客户端,AccuREST从提供的DSL生成WireMock存根,以便可以为该API的客户端提供可靠的存根。

什么是Stub Runner?

现在,我们记得AccuREST做什么了,我们可以更深入地研究Stub Runner 。 假设我们有以下服务流程(顺便说一下,这是Zipkin与Spring Cloud Sleuth集成的屏幕截图 )

depends_accurest

让我们想象一下自己作为服务2的开发商-的一个呼叫服务3服务 。 因为我们正在做的CDC( 消费者驱动的契约 )的方式让我们假定服务3服务的存根得到了已部署到一些Maven仓库。

如果我写服务2的集成测试我肯定有服务3服务互动的一些要点。 在大多数情况下,我很可能会在代码中模拟这些交互,但是对其他应用程序进行真正的HTTP调用将非常有价值。 当然,我不想下载这两种服务并只为进行集成测试而运行它们-这太过分了。 这就是为什么此时最可取的解决方案是运行我的协作者的存根。

由于我懒于手动执行操作,因此我希望自动为我下载存根,因此WireMock服务器将启动并提供存根定义。

这正是Stub Runner可以为您做的!

它是如何工作的?

概念

Stub Runner的核心是使用Groovy的Grape机制从给定的Maven存储库下载存根。 接下来,将它们解压缩到一个临时文件夹。 假设您在存根JAR中具有WireMock存根的以下结构(service3 service3-stubs.jar

├── META-INF
│   └── MANIFEST.MF
└── mappings└── service3├── shouldMarkClientAsFraud.json├── notAWireMockMapping.json└── shouldSayHello.json

Stub Runner将扫描整个解压缩的JAR中是否有任何.json文件。 约定将存根定义放在mappings文件夹下。 因此,它将选择shouldMarkClientAsFraud.jsonnotAWireMockMapping.jsonshouldSayHello.json文件。

接下来,为每个依赖项启动一个WireMock实例,并尝试将每个找到的JSON解析为WireMock存根定义。 此时任何异常都将被忽略(因此,假设notAWireMockMapping.json不是有效的WireMock定义,该异常将被抑制)。 在我们的场景2 WireMock服务器将启动-一个用于service3 ,一个用于service4

这样,您不必手动复制存根。 由于存根存储在Maven存储库中,因此它们是集中式的。 这是非常重要的原因,因为Stub Runner总是下载最新版本的Stub,因此您可以确保一旦有人进行了不兼容的更改,测试就会中断。

API

从开发人员的角度来看,应该只使用少数几个Stub Runner的类。 在大多数情况下,您将使用以下内容:

存根查找器

该接口允许您查找已启动的WireMock实例的URL。 您可以通过传递Ivy表示法( groupId:artifactId )或仅获得artifactId来找到该URL, Stub Runner将尝试处理其余部分。

interface StubFinder {/*** For the given groupId and artifactId tries to find the matching* URL of the running stub.** @param groupId - might be null. In that case a search only via artifactId takes place* @return URL of a running stub or null if not found*/URL findStubUrl(String groupId, String artifactId)/*** For the given Ivy notation {@code groupId:artifactId} tries to find the matching* URL of the running stub. You can also pass only {@code artifactId}.** @param ivyNotation - Ivy representation of the Maven artifact* @return URL of a running stub or null if not found*/URL findStubUrl(String ivyNotation)/*** Returns all running stubs*/RunningStubs findAllRunningStubs()
}

RunningStubs

表示已经运行的存根的结构。 给您一些帮助方法,以检索特定存根的常春藤表示,找到存根的端口等。

running_stubs

存根运行

可以运行存根的类的合同:

interface StubRunning extends Closeable, StubFinder {/*** Runs the stubs and returns the {@link RunningStubs}*/RunningStubs runStubs()}

StubRunner

表示一个现成的存根实例。 它可以运行存根并返回到运行实例的WireMock包裹在RunningStubs类。 由于正在实现StubFinder因此,如果当前的groupid和artifactid与相应的正在运行的stub相匹配,也可以查询StubFinder

BatchStubRunner

如果您要使用存根运行WireMocks的多个服务,则足以使用BatchStubRunner 。 迭代StubRunner的给定Iterable ,并在每个StubRunner执行逻辑。

正在运行的Stub Runner

在下面的所有示例中,我们假设存根存储在Maven存储库中,该存储库位于http://toomuchcoding.com URL下。 作为服务2我想下载的存根com.toomuchcoding:service3com.toomuchcoding:service4服务。

存根赛跑者作为胖胖的JAR

如何使用它?

Stub Runner带有一个主类( io.codearte.accurest.stubrunner.StubRunnerMain ),您可以使用以下选项运行它:

-maxp (--maxPort) N            : Maximum port value to be assigned to theWiremock instance. Defaults to 15000(default: 15000)-minp (--minPort) N            : Minimal port value to be assigned to theWiremock instance. Defaults to 10000(default: 10000)-s (--stubs) VAL               : Comma separated list of Ivy representation ofjars with stubs. Eg. groupid:artifactid1,groupid2:artifactid2:classifier-sr (--stubRepositoryRoot) VAL : Location of a Jar containing server where youkeep your stubs (e.g. http://nexus.net/content/repositories/repository)-ss (--stubsSuffix) VAL        : Suffix for the jar containing stubs (e.g.'stubs' if the stub jar would have a 'stubs'classifier for stubs: foobar-stubs ).Defaults to 'stubs' (default: stubs)-wo (--workOffline)            : Switch to work offline. Defaults to 'false'(default: false)

您可以从IDE运行该主类,也可以自己构建一个胖JAR。 为此,只需调用以下命令:

./gradlew stub-runner-root:stub-runner:shadowJar -PfatJar

然后在build/lib内部将有一个带有分类器fatJar的胖JAR,等待您执行。

再回到我们的例子中,一旦脂肪JAR建我只是调用下面的命令检索服务3服务的存根从Maven仓库提供http://toomuchcoding.com

java -jar stub-runner-1.0.4-SNAPSHOT-fatJar.jar -sr http://toomuchcoding.com -s com.toomuchcoding:service3:stubs,com.toomuchcoding.service4

什么时候使用?

当您在不想下载并运行该应用程序的所有协作者的已部署应用程序上运行一些快速冒烟测试时,将Stub Runner作为主要类运行是最有意义的。 有关这种方法背后的更多原理,您可以查看我有关微服务部署的文章

Stub Runner JUnit规则

如何使用它?

您可以使用Stub Runner的 JUnit规则在测试过程中自动下载并运行存根。 AccurestRule实现了StubFinder界面,因此您可以轻松地找到您感兴趣的服务的URL。

这是使用Spock的方法:

class SomeSpec extends Specification {@ClassRule @Shared AccurestRule rule = new AccurestRule().repoRoot('http://toomuchcoding.com').downloadStub("com.toomuchcoding", "service3").downloadStub("com.toomuchcoding:service4")def 'should do something useful when service3 is called'() {given:URL service3Url = rule.findStubUrl('com.toomuchcoding', 'service3')expect:somethingUseful(service3Url)}def 'should do something even more useful when service4 is called'() {given:URL service4Url = rule.findStubUrl('service4')expect:somethingMoreUseful(service4Url)}
}

或使用普通的Java JUnit:

public class SomeTest {@ClassRule public static AccurestRule rule = new AccurestRule().repoRoot("http://toomuchcoding.com").downloadStub("com.toomuchcoding", "service3").downloadStub("com.toomuchcoding:service4");@Testpublic void should_do_something_useful_when_service3_is_called() {URL service3Url = rule.findStubUrl("com.toomuchcoding", "service3");somethingUseful(service3Url);}@Testpublic void should_do_something_even_more_useful_when_service4_is_called() {URL service4Url = rule.findStubUrl("service4");somethingMoreUseful(service4Url);}
}

什么时候使用?

如果我们不提供与现有框架的任何集成,则可以在任意位置使用此规则。

存根赛跑者春天

如何使用它?

您可以使用Stub Runner的 Spring配置来下载协作者的Stub,并在Spring上下文启动时运行WireMock服务器。 我们提供了可以在测试中导入的StubRunnerConfiguration 。 在该配置中,我们注册了一个StubFinder bean,您可以在测试中自动装配它。

具有以下application.yaml文件:

stubrunner.stubs.repository.root: http://toomuchcoding.com
stubrunner.stubs.ids: com.toomuchcoding:service3:stubs,com.toomuchcoding.service4

这就是用Spock可以做到的

@ContextConfiguration(classes = Config, loader = SpringApplicationContextLoader)
class StubRunnerConfigurationSpec extends Specification {@Autowired StubFinder stubFinderdef 'should do something useful when service3 is called'() {given:URL service3Url = stubFinder.findStubUrl('com.toomuchcoding', 'service3')expect:somethingUseful(service3Url)}def 'should do something even more useful when service4 is called'() {given:URL service4Url = stubFinder.findStubUrl('service4')expect:somethingMoreUseful(service4Url)}@Configuration@Import(StubRunnerConfiguration)@EnableAutoConfigurationstatic class Config {}}

什么时候使用?

在您的测试中,如果您拥有Spring而没有Spring Cloud。 您也可以在编译时添加它(当然,您必须添加一些Spring概要文件,以便不在生产环境中运行它),以从运行微服务的“开发人员”模式中获利。 这意味着,如果您启动应用程序以单击它,那么周围的所有存根都将已经下载并启动。

存根赛跑者春天云

如何使用它?

当使用Spring Cloud的服务发现抽象和Netflix Ribbon时,您可以使用Stub Runner的 Spring Cloud配置来从Stubed合作者中获利。 Stub Runner Spring Cloud配置是AutoConfiguration因此会自动为您启动。

让我们假设你指的是作为服务3 service3在你的代码,并作为服务4 shouldMapThisNameToService4 。 这意味着您正在以以下方式使用例如@LoadBalanced RestTemplate (不要像本例中那样使用字段注入!):

@Component
class SomeClass {@Autowired @LoadBalanced RestTemplate restTemplatevoid doSth() {// code...String service3Response = restTemplate.getForObject('http://service3/name', String)String service4Response = restTemplate.getForObject('http://shouldMapThisNameToService4/name', String)// more code...}}

如果您用来调用其他服务的服务ID准确地映射到Maven存储库中的工件ID的名称,那么您很幸运,无需执行任何操作即可找到正在运行的存根。 但是,如果不是这种情况–不用担心,您只需要自己映射即可。

stubrunner.stubs.idsToServiceIds属性是映射的根路径,其中的是下载的存根的artifactID是代码中使用的serviceId

具有以下application.yaml文件:

stubrunner.stubs.repository.root: http://toomuchcoding.com
stubrunner.stubs.ids: com.toomuchcoding:service3:stubs,com.toomuchcoding.service4stubrunner.stubs.idsToServiceIds:service4: shouldMapThisNameToService4

这就是用Spock可以做到的

@ContextConfiguration(classes = Config, loader = SpringApplicationContextLoader)
class StubRunnerConfigurationSpec extends Specification {@Autowired SomeClass someClassdef 'should not explode'() {when:someClass.doSth()expect:noExceptionThrown()}@Configuration@EnableAutoConfigurationstatic class Config {}}

什么时候使用?

当您使用Spring Cloud时。 您也可以以“开发人员”模式从Stub Runner Spring Cloud获利,如Stub Runner Spring部分所述。

其他配置选项

您可以通过系统属性设置Maven存储库的默认值:

-Dstubrunner.stubs.repository.root=http://your.maven.repo.com

可配置属性的列表包含:

名称 默认值 描述
stubrunner.port.range.min 10000 WireMock服务器的端口的最小值
stubrunner.port.range.max 15000 WireMock服务器的端口最大值
stubrunner.stubs.repository.root M2仓库的地址(如果未提供,将指向本地M2仓库)
stubrunner.stubs.classifier 存根 包含存根的JAR的默认分类器
stubrunner.work-offline 应该尝试连接到任何存储库以下载存根(如果没有互联网,则很有用)
存根 默认逗号分隔的存根列表以供下载

摘要

短跑选手

  • 已经被证明是进行CDC时非常有用的工具。
  • 经过了战斗测试,越来越多的公司宣布有兴趣使用它。
  • 帮助您生成一个API,该API应该使双方(服务器和客户端)同等高兴(或不高兴,但他们的情感仍然平等;))。
  • 语言/技术不可知–您可以将其作为胖JAR来运行,可以将其与Spring,Guice或任何您想要的东西一起使用。
  • 从API设计和兼容性角度来看,都可以帮助您加快反馈周期。

链接

  • AccuREST Github存储库
  • 短跑选手维基
  • AccuREST Gitter

翻译自: https://www.javacodegeeks.com/2016/04/accurest-stub-runner-released.html

stub

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

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

相关文章

kali linux wifi监听模式,无线渗透教程1:监听无线网络

第一:配置管理无线网卡1.1这里,我们使用tplink wn722n, kali linux插上即用,无需安装驱动。1.2Vmare虚拟机配置如下:如网卡插入到电脑后,先将虚拟机设置成桥接模式之后对虚拟机进行配置之后呢,我们在终端窗…

matlab的7.3版本是什么_王者荣耀:玩不好元歌的3大原因,无论什么版本,元歌起码T1.5_电竞...

很多高段位元歌并不是以秀为核心的,而是他们就像一个冷静的杀手,在一闪即逝却又最合适的时机里,他能正确的选择进场的方式,以及击杀的方式。说白了,元歌的进场手段并没有多少,什么时候用傀儡433上去锁人&am…

【WebRTC---入门篇】(一)WebRTC整体架构

1.绿色部分是WebRTC核心部分(核心库) 2.紫色部分是JS提供的API(应用层) 整体是应用层调用核心层。 核心层,第一层 C++ API 提供给外面的接口。最主要的是(PeerConnedtion 对等连接)。 核心层,第二层 Session 上下文管理层(音视频)。 核心层,第三层[最重要的…

aws sqs_AWS SQS和Spring JMS集成

aws sqsAmazon WEB服务为我们提供了SQS消息传递服务。 sqs的java sdk与JMS兼容。 因此,可以将SQS与spring提供的JMS集成框架集成在一起,而不是将SQS用作简单的spring bean。 我将使用spring-boot和gradle。 gradle文件: group com.gkatzi…

linux ntfs 新建,Linux在NTFS中创建的文件的权限

我正在尝试使用以下设置在Linux中挂载NTFS文件系统:>在Linux中,NTFS中的所有文件和目录都应归root所有并获得团体胜利.权限应设置为775.> Linux在NTFS文件系统中创建的所有文件和目录都应该在Windows中具有与目录相同的所有权和权限包含新创建的文件或目录.为…

python 创建空的numpy数组_数据分析-NumPy内置函数创建数组

微信公众号:yale记关注可了解更多的教程问题或建议,请公众号留言。背景介绍今天学习使用numpy的内置函数arange()、ones()、zeros()、linspace() 等内置函数创建数组,对于使用数据结构和多维列表非常有用,可以节省大量的时间。入门…

c语言课全部由字母,C语言程序设计课程期末练习试题.doc

C语言程序设计课程期末练习题一、单项选择题。把合适的选项编号填写在括号内。1.不符合C语言规定的复合语句是( )。DA.{} B.{;} C.{x0;} D.{y10}2.C语言中的选择类语句有两条,它们是( )。AA&…

java8返回单个号码_如何在单个API中支持Java 6、8、9

java8返回单个号码借助jOOQ 3.7&#xff0c;我们终于添加了对Java 8功能的正式支持。 这为许多不错的改进打开了大门&#xff0c;例如&#xff1a; 创建结果流 try (Stream<Record2<String, String>> stream DSL.using(configuration).select(FIRST_NAME, LAST_N…

使用t-sql语句修改表中的某些数据及数据类型。_数据库基本理论详细介绍

1、数据库范式第一范式&#xff1a;列不可分&#xff0c;eg:【联系人】(姓名&#xff0c;性别&#xff0c;电话)&#xff0c;一个联系人有家庭电话和公司电话&#xff0c;那么这种表结构设计就没有达到 1NF&#xff1b;第二范式&#xff1a;有主键&#xff0c;保证完全依赖。eg…

spring-retry_使用Spring-Retry重试处理

spring-retry每当软件组件相互通信时&#xff0c;就有可能出现暂时的自我纠正错误。 这些故障包括服务的暂时不可用&#xff0c;网络连接的瞬时丢失或服务繁忙时出现的超时。 在这种情况下&#xff0c;适当的重试处理可以减少这些故障可能引起的问题。 在这篇文章中&#xff0…

【WebRTC---入门篇】(三)WebRTC运行机制

轨和流 Track 轨&#xff1a;音频轨和视频轨是不相交的 MediaStream 媒体流&#xff1a;中包含多个音视频轨 WebRTC重要类 MediaStream 负责添加N个轨&#xff0c;加入到RTCPeerConnection RTCPeerConnection 核心 RTCDataChannel 非音视频数据&#xff0c;通过RTCP…

a - 数据结构实验之串一:kmp简单应用_【在线教学示范课案例】数据结构(刘航)...

一、教师简介刘航&#xff0c;网络空间安全学院教师&#xff0c;本科生“数据结构”、“算法设计综合实验” 和研究生“算法设计与优化”课程的主讲教师。近年来积极开展了教学与考核模式改革、探究式/研究型课程等课程改革探索&#xff0c;探索课程、学科竞赛和项目相结合的科…

c语言创建字符树,使用C语言构建基本的二叉树数据结构

二叉树结构常用的一些初始化代码#include#includetypedef struct Node{int data;Node *leftchild;Node *rightchild;}Node;/*初始化一棵二叉树排序树。*/void InitBinaryTree(Node**root,int elem){*root(Node*)malloc(sizeof(Node));if(!(*root)){printf("Memory allocat…

可变lambda_Lambda的Lambda(如果可选)

可变lambda因此&#xff0c;我对JDK 8中Optional接口的两个限制感到沮丧。第一个问题是&#xff0c;没有明显的方法可以在块中执行else操作&#xff0c;因为只有isPresent方法&#xff0c;除非您使用的是老式的if语句。 第二个问题当然是古老的板栗&#xff0c;即使您能够做到&…

【WebRTC---入门篇】(四)WebRTC设备管理

enumerateDevices API用来获取音视频设备 JS使用单线程处理&#xff0c;为了避免阻塞。使用异步调用Promise。handle为处理函数&#xff0c;处理主要逻辑。成功调用resolve&#xff1b;失败调用reject。Promise可以注册两个方法 then(逻辑处理成功会收到on_resolve) 和 catch(…

n阶幻方c语言编程,求单偶阶与双偶阶幻方编程思想及其算法!

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼#include #define N 100void oujie(int oushu){int a[N][N]{0},i,j,k1,n,m;noushu/2;m(oushu-2)/4;for(i1,j3*n/2;k<n*n;){if(i<0){ ii3*n; continue; }if(j>3*n){ jj-3*n; continue; }if(j<0){ jj3*n; continue; }if(…

python函数结构_PYTHON 之结构体,全局变量,函数参数,lambda编程 等

PYTHON 之结构体,全局变量,函数参数,lambda编程 ,generator&#xff08;yield&#xff09;使用以及如何自己构建switch结构 *********************** pass pass可以模拟struct结构 class Data pass d Data() d.a 2 d.b 4 print d.a print d.b *********************** 子函数…

【音视频安卓开发 (六)】Android GLSurfaceView播放视频

GLSurfaceView渲染RGB的数据,利用双缓冲空间机制。取出缓冲地址,将要渲染的数据copy到缓冲地址. 获取Surface Java部分&#xff1a; SurfaceView控件设置到界面中显示 SurfaceView定义一个类来实现 package com.example.hello;import android.content.Context; import android…

什么是openstack_您在OpenStack Summit 2016上错过了什么

什么是openstack今年&#xff0c;我第一次参加了4月25日至29日在德克萨斯州奥斯汀举行的OpenStack峰会。 今天结束了&#xff0c;我要回家了&#xff0c;我想回顾一下&#xff0c;从我的角度分享你错过的事情。 作为以应用程序开发人员为重点的技术传播者&#xff0c;转移到包…