W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
與存根相關的最大挑戰(zhàn)之一是它們的可重用性。只有將它們廣泛使用,它們才能達到目的。通常使困難的是請求/響應元素的硬編碼值。例如日期或ID。想象以下JSON請求
{ "time" : "2016-10-10 20:10:15", "id" : "9febab1c-6f36-4a0b-88d6-3b6a6d81cd4a", "body" : "foo" }
和JSON響應
{ "time" : "2016-10-10 21:10:15", "id" : "c4231e1f-3ca9-48d3-b7e7-567d55f0d051", "body" : "bar" }
想象一下通過更改系統(tǒng)中的時鐘或提供數(shù)據(jù)提供者的存根實現(xiàn)來設置time
字段的適當值(讓我們假定此內(nèi)容是由數(shù)據(jù)庫生成)所需的痛苦。與名為id
的字段相同。您將創(chuàng)建UUID生成器的存根實現(xiàn)嗎?毫無意義...
因此,作為消費者,您希望發(fā)送與任何時間形式或任何UUID匹配的請求。這樣,您的系統(tǒng)將像往常一樣工作-會生成數(shù)據(jù),而您無需存根任何東西。假設在上述JSON的情況下,最重要的部分是body
字段。您可以專注于此并為其他字段提供匹配。換句話說,您希望存根像這樣工作:
{ "time" : "SOMETHING THAT MATCHES TIME", "id" : "SOMETHING THAT MATCHES UUID", "body" : "foo" }
就響應作為消費者而言,您需要可以操作的具體價值。所以這樣的JSON是有效的
{ "time" : "2016-10-10 21:10:15", "id" : "c4231e1f-3ca9-48d3-b7e7-567d55f0d051", "body" : "bar" }
如您在前幾節(jié)中所看到的,我們根據(jù)合同生成測試。因此,從生產(chǎn)者的角度來看,情況似乎大不相同。我們正在解析提供的合同,并且在測試中我們想向您的端點發(fā)送真實請求。因此,對于請求的生產(chǎn)者而言,我們無法進行任何形式的匹配。我們需要生產(chǎn)者后端可以使用的具體價值。這樣的JSON是有效的:
{ "time" : "2016-10-10 20:10:15", "id" : "9febab1c-6f36-4a0b-88d6-3b6a6d81cd4a", "body" : "foo" }
另一方面,從合同有效性的角度來看,響應不一定包含time
或id
的具體值。假設您是在生產(chǎn)者端生成的-再次,您必須進行大量的存根操作以確保始終返回相同的值。因此,從生產(chǎn)者的角度來看,您可能想要以下響應:
{ "time" : "SOMETHING THAT MATCHES TIME", "id" : "SOMETHING THAT MATCHES UUID", "body" : "bar" }
那么,您如何才能一次為消費者提供匹配者,為生產(chǎn)者提供具體價值,反之亦然?在Spring Cloud Contract中,我們允許您提供動態(tài)值。這意味著通信的雙方可能會有所不同。您可以傳遞值:
通過value
方法
value(consumer(...), producer(...)) value(stub(...), test(...)) value(client(...), server(...))
或使用$()
方法
$(consumer(...), producer(...)) $(stub(...), test(...)) $(client(...), server(...))
您可以在Contract DSL部分中了解有關此內(nèi)容的更多信息。
調(diào)用value()
或$()
會告訴Spring Cloud Contract您將傳遞動態(tài)值。在consumer()
方法內(nèi)部,傳遞應該在使用者方(在生成的存根中)使用的值。在producer()
方法內(nèi)部,傳遞應該在生產(chǎn)方(在生成的測試中)使用的值。
如果一側(cè)傳遞了正則表達式,而另一側(cè)則沒有傳遞,則另一側(cè)將自動生成。
通常,您會將該方法與regex
幫助方法一起使用。例如consumer(regex('[0-9]{10}'))
。
概括起來,上述情況的合同看起來或多或少像這樣(時間和UUID的正則表達式已簡化,很可能是無效的,但在此示例中,我們希望保持非常簡單):
org.springframework.cloud.contract.spec.Contract.make { request { method 'GET' url '/someUrl' body([ time : value(consumer(regex('[0-9]{4}-[0-9]{2}-[0-9]{2} [0-2][0-9]-[0-5][0-9]-[0-5][0-9]')), id: value(consumer(regex('[0-9a-zA-z]{8}-[0-9a-zA-z]{4}-[0-9a-zA-z]{4}-[0-9a-zA-z]{12}')) body: "foo" ]) } response { status OK() body([ time : value(producer(regex('[0-9]{4}-[0-9]{2}-[0-9]{2} [0-2][0-9]-[0-5][0-9]-[0-5][0-9]')), id: value([producer(regex('[0-9a-zA-z]{8}-[0-9a-zA-z]{4}-[0-9a-zA-z]{4}-[0-9a-zA-z]{12}')) body: "bar" ]) } }
請閱讀與JSON相關的Groovy文檔,以了解如何正確構(gòu)造請求/響應主體。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: