stub_AccuREST Stub Runner发布
stub
最近發(fā)布時間不錯! 我在Too Much Coding博客上的博客更多是關(guān)于發(fā)布,然后是關(guān)于任何具體主題;)
在作為Brixton RC1的一部分發(fā)布Spring Cloud Sleuth之后,我們剛剛發(fā)布了AccuREST 1.0.4版本。 我們修復(fù)了一些錯誤,但引入了一些重要功能,包括:
- Maven插件支持
 - Stub Runner功能
 
這篇文章將更深入地介紹后者。
介紹
我已經(jīng)對名為Micro-Infra-Spring的庫進(jìn)行了很多討論,在其中我介紹了如何從Stub Runner功能中受益。 自從我離開擁有該存儲庫的公司以來,幾乎根本沒有維護(hù)該項(xiàng)目。 很長一段時間以來,任何開發(fā)工作都是我自己完成的,實(shí)際上,我是大多數(shù)Stub Runner代碼的作者。 由于上述原因以及Stub Runner與AccuREST的stub生成功能緊密結(jié)合的事實(shí),我決定將其遷移到AccuREST的存儲庫。
AccuREST回顧
Stub Runner與AccuREST的概念緊密結(jié)合。 有關(guān)AccuREST的更多信息,您可以檢查我的博客條目或在Github上檢查AccuREST項(xiàng)目 。 如果您不知道那是什么,我會盡力快速回顧一下。
AccuREST是消費(fèi)者驅(qū)動的合同驗(yàn)證器,您可以在其中通過Groovy DSL定義API的合同。 從該DSL,在服務(wù)器端,將創(chuàng)建測試以檢查您的合同是否說實(shí)話。 從Stub Runner的角度來看,更有趣的是客戶端。 對于客戶端,AccuREST從提供的DSL生成WireMock存根,以便可以為該API的客戶端提供可靠的存根。
什么是Stub Runner?
現(xiàn)在,我們記得AccuREST做什么了,我們可以更深入地研究Stub Runner 。 假設(shè)我們有以下服務(wù)流程(順便說一下,這是Zipkin與Spring Cloud Sleuth集成的屏幕截圖 )
讓我們想象一下自己作為服務(wù)2的開發(fā)商-的一個呼叫服務(wù)3和服務(wù) 。 因?yàn)槲覀冋谧龅腃DC( 消費(fèi)者驅(qū)動的契約 )的方式讓我們假定服務(wù)3和服務(wù)的存根得到了已部署到一些Maven倉庫。
如果我寫服務(wù)2的集成測試我肯定有服務(wù)3和服務(wù)互動的一些要點(diǎn)。 在大多數(shù)情況下,我很可能會在代碼中模擬這些交互,但是對其他應(yīng)用程序進(jìn)行真正的HTTP調(diào)用將非常有價(jià)值。 當(dāng)然,我不想下載這兩種服務(wù)并只為進(jìn)行集成測試而運(yùn)行它們-這太過分了。 這就是為什么此時最可取的解決方案是運(yùn)行我的協(xié)作者的存根。
由于我懶于手動執(zhí)行操作,因此我希望自動為我下載存根,因此WireMock服務(wù)器將啟動并提供存根定義。
這正是Stub Runner可以為您做的!
它是如何工作的?
概念
Stub Runner的核心是使用Groovy的Grape機(jī)制從給定的Maven存儲庫下載存根。 接下來,將它們解壓縮到一個臨時文件夾。 假設(shè)您在存根JAR中具有WireMock存根的以下結(jié)構(gòu)(service3 service3-stubs.jar )
├── META-INF │ └── MANIFEST.MF └── mappings└── service3├── shouldMarkClientAsFraud.json├── notAWireMockMapping.json└── shouldSayHello.jsonStub Runner將掃描整個解壓縮的JAR中是否有任何.json文件。 約定將存根定義放在mappings文件夾下。 因此,它將選擇shouldMarkClientAsFraud.json , notAWireMockMapping.json和shouldSayHello.json文件。
接下來,為每個依賴項(xiàng)啟動一個WireMock實(shí)例,并嘗試將每個找到的JSON解析為WireMock存根定義。 此時任何異常都將被忽略(因此,假設(shè)notAWireMockMapping.json不是有效的WireMock定義,該異常將被抑制)。 在我們的場景2 WireMock服務(wù)器將啟動-一個用于service3 ,一個用于service4 。
這樣,您不必手動復(fù)制存根。 由于存根存儲在Maven存儲庫中,因此它們是集中式的。 這是非常重要的原因,因?yàn)镾tub Runner總是下載最新版本的Stub,因此您可以確保一旦有人進(jìn)行了不兼容的更改,測試就會中斷。
API
從開發(fā)人員的角度來看,應(yīng)該只使用少數(shù)幾個Stub Runner的類。 在大多數(shù)情況下,您將使用以下內(nèi)容:
存根查找器
該接口允許您查找已啟動的WireMock實(shí)例的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
表示已經(jīng)運(yùn)行的存根的結(jié)構(gòu)。 給您一些幫助方法,以檢索特定存根的常春藤表示,找到存根的端口等。
存根運(yùn)行
可以運(yùn)行存根的類的合同:
interface StubRunning extends Closeable, StubFinder {/*** Runs the stubs and returns the {@link RunningStubs}*/RunningStubs runStubs()}StubRunner
表示一個現(xiàn)成的存根實(shí)例。 它可以運(yùn)行存根并返回到運(yùn)行實(shí)例的WireMock包裹在RunningStubs類。 由于正在實(shí)現(xiàn)StubFinder因此,如果當(dāng)前的groupid和artifactid與相應(yīng)的正在運(yùn)行的stub相匹配,也可以查詢StubFinder 。
BatchStubRunner
如果您要使用存根運(yùn)行WireMocks的多個服務(wù),則足以使用BatchStubRunner 。 迭代StubRunner的給定Iterable ,并在每個StubRunner執(zhí)行邏輯。
正在運(yùn)行的Stub Runner
在下面的所有示例中,我們假設(shè)存根存儲在Maven存儲庫中,該存儲庫位于http://toomuchcoding.com URL下。 作為服務(wù)2我想下載的存根com.toomuchcoding:service3和com.toomuchcoding:service4服務(wù)。
存根賽跑者作為胖胖的JAR
如何使用它?
Stub Runner帶有一個主類( io.codearte.accurest.stubrunner.StubRunnerMain ),您可以使用以下選項(xiàng)運(yùn)行它:
-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運(yùn)行該主類,也可以自己構(gòu)建一個胖JAR。 為此,只需調(diào)用以下命令:
./gradlew stub-runner-root:stub-runner:shadowJar -PfatJar然后在build/lib內(nèi)部將有一個帶有分類器fatJar的胖JAR,等待您執(zhí)行。
再回到我們的例子中,一旦脂肪JAR建我只是調(diào)用下面的命令檢索服務(wù)3和服務(wù)的存根從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什么時候使用?
當(dāng)您在不想下載并運(yùn)行該應(yīng)用程序的所有協(xié)作者的已部署應(yīng)用程序上運(yùn)行一些快速冒煙測試時,將Stub Runner作為主要類運(yùn)行是最有意義的。 有關(guān)這種方法背后的更多原理,您可以查看我有關(guān)微服務(wù)部署的文章
Stub Runner JUnit規(guī)則
如何使用它?
您可以使用Stub Runner的 JUnit規(guī)則在測試過程中自動下載并運(yùn)行存根。 AccurestRule實(shí)現(xiàn)了StubFinder界面,因此您可以輕松地找到您感興趣的服務(wù)的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);} }什么時候使用?
如果我們不提供與現(xiàn)有框架的任何集成,則可以在任意位置使用此規(guī)則。
存根賽跑者春天
如何使用它?
您可以使用Stub Runner的 Spring配置來下載協(xié)作者的Stub,并在Spring上下文啟動時運(yùn)行WireMock服務(wù)器。 我們提供了可以在測試中導(dǎo)入的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。 您也可以在編譯時添加它(當(dāng)然,您必須添加一些Spring概要文件,以便不在生產(chǎn)環(huán)境中運(yùn)行它),以從運(yùn)行微服務(wù)的“開發(fā)人員”模式中獲利。 這意味著,如果您啟動應(yīng)用程序以單擊它,那么周圍的所有存根都將已經(jīng)下載并啟動。
存根賽跑者春天云
如何使用它?
當(dāng)使用Spring Cloud的服務(wù)發(fā)現(xiàn)抽象和Netflix Ribbon時,您可以使用Stub Runner的 Spring Cloud配置來從Stubed合作者中獲利。 Stub Runner Spring Cloud配置是AutoConfiguration因此會自動為您啟動。
讓我們假設(shè)你指的是作為服務(wù)3 service3在你的代碼,并作為服務(wù)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...}}如果您用來調(diào)用其他服務(wù)的服務(wù)ID準(zhǔn)確地映射到Maven存儲庫中的工件ID的名稱,那么您很幸運(yùn),無需執(zhí)行任何操作即可找到正在運(yùn)行的存根。 但是,如果不是這種情況–不用擔(dān)心,您只需要自己映射即可。
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 {}}什么時候使用?
當(dāng)您使用Spring Cloud時。 您也可以以“開發(fā)人員”模式從Stub Runner Spring Cloud獲利,如Stub Runner Spring部分所述。
其他配置選項(xiàng)
您可以通過系統(tǒng)屬性設(shè)置Maven存儲庫的默認(rèn)值:
-Dstubrunner.stubs.repository.root=http://your.maven.repo.com可配置屬性的列表包含:
| stubrunner.port.range.min | 10000 | WireMock服務(wù)器的端口的最小值 | 
| stubrunner.port.range.max | 15000 | WireMock服務(wù)器的端口最大值 | 
| stubrunner.stubs.repository.root | M2倉庫的地址(如果未提供,將指向本地M2倉庫) | |
| stubrunner.stubs.classifier | 存根 | 包含存根的JAR的默認(rèn)分類器 | 
| stubrunner.work-offline | 假 | 應(yīng)該嘗試連接到任何存儲庫以下載存根(如果沒有互聯(lián)網(wǎng),則很有用) | 
| 存根 | 默認(rèn)逗號分隔的存根列表以供下載 | 
摘要
短跑選手 :
- 已經(jīng)被證明是進(jìn)行CDC時非常有用的工具。
 - 經(jīng)過了戰(zhàn)斗測試,越來越多的公司宣布有興趣使用它。
 - 幫助您生成一個API,該API應(yīng)該使雙方(服務(wù)器和客戶端)同等高興(或不高興,但他們的情感仍然平等;))。
 - 語言/技術(shù)不可知–您可以將其作為胖JAR來運(yùn)行,可以將其與Spring,Guice或任何您想要的東西一起使用。
 - 從API設(shè)計(jì)和兼容性角度來看,都可以幫助您加快反饋周期。
 
鏈接
- AccuREST Github存儲庫
 - 短跑選手維基
 - AccuREST Gitter
 
翻譯自: https://www.javacodegeeks.com/2016/04/accurest-stub-runner-released.html
stub
總結(jié)
以上是生活随笔為你收集整理的stub_AccuREST Stub Runner发布的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 电脑内存信息怎么看电脑内存如何查看
 - 下一篇: 苹果笔记本电脑怎么安装windows系统