Spotrebiteľom riadené zmluvy s Paktom

1. Prehľad

V tomto rýchlom článku sa pozrieme na koncept zmlúv riadených spotrebiteľmi.

Budeme testovať integráciu s externou službou REST prostredníctvom zmluvy, ktorú definujeme pomocou Pakt knižnica. Túto zmluvu môže definovať klient, potom si ju môže vyzdvihnúť poskytovateľ a použiť na vývoj svojich služieb.

Vytvoríme tiež testy na základe zmluvy pre klientsku aj poskytovateľskú aplikáciu.

2. Čo je Pakt?

Použitím Pakt, môžeme definovať očakávania spotrebiteľov pre daného poskytovateľa (ktorým môže byť služba HTTP REST) ​​vo forme zmluvy (odtiaľ názov knižnice).

Chystáme sa uzavrieť túto zmluvu pomocou DSL poskytnutého spoločnosťou Pakt. Po definovaní môžeme testovať interakcie medzi spotrebiteľmi a poskytovateľom pomocou fingovanej služby, ktorá je vytvorená na základe definovanej zmluvy. Službu tiež otestujeme oproti zmluve pomocou falošného klienta.

3. Maven závislosť

Na začiatok budeme musieť pridať závislosť Maven pact-jvm-consumer-junit_2.11 knižnica:

 test au.com.dius pact-jvm-consumer-junit_2.11 3.5.0 

4. Definovanie zmluvy

Keď chceme vytvoriť test pomocou Pakt, najskôr musíme definovať a @ Pravidlo ktoré sa použijú v našom teste:

@Rule public PactProviderRuleMk2 mockProvider = nový PactProviderRuleMk2 ("test_provider", "localhost", 8080, toto);

Predávame meno poskytovateľa, hostiteľa a port, na ktorom bude spustený falošný server (ktorý je vytvorený na základe zmluvy).

Povedzme, že služba definovala zmluvu pre dve metódy HTTP, ktoré dokáže spracovať.

Prvou metódou je požiadavka GET, ktorá vráti JSON s dvoma poľami. Keď je žiadosť úspešná, vráti kód odpovede 200 HTTP a znak C.typ typu ontent hlavička pre JSON.

Definujme takúto zmluvu pomocou Pakt.

Musíme použiť @Pact anotáciu a meno spotrebiteľa, pre ktoré je zmluva definovaná. Vo vnútri komentovanej metódy môžeme definovať našu zmluvu GET:

@Pact (consumer = "test_consumer") public RequestResponsePact createPact (PactDslWithProvider builder) {Map headers = new HashMap (); headers.put ("Content-Type", "application / json"); return builder .given ("test GET") .uponReceiving ("GET REQUEST") .path ("/ pact") .method ("GET") .willRespondWith () .status (200) .headers (headers) .body ( "{\" condition \ ": true, \" name \ ": \" tom \ "}") (...)}

Pomocou Pakt DSL definujeme, že pre danú požiadavku GET chceme vrátiť odpoveď 200 s konkrétnymi hlavičkami a telom.

Druhou časťou našej zmluvy je metóda POST. Keď klient pošle požiadavku POST na cestu / pakt so správnym telom JSON vráti 201 kód odpovede HTTP.

Definujme takúto zmluvu s Pakt:

(...) .given ("test POST") .uponReceiving ("POST REQUEST") .method ("POST") .headers (headers) .body ("{\" name \ ": \" Michael \ "} ") .path (" / pact ") .willRespondWith () .status (201) .toPact ();

Upozorňujeme, že musíme zavolať na toPact () metóda na konci zmluvy na vrátenie inštancie RequestResponsePact.

4.1. Artefakt výsledného paktu

Súbory Pact sa predvolene generujú v cieľ / pakty priečinok. Na prispôsobenie tejto cesty môžeme nakonfigurovať maven-surefire-plugin:

 org.apache.maven.plugins cieľ maven-surefire-plugin / mypacts ... 

Zostava Maven vygeneruje súbor s názvom test_consumer-test_provider.json v target / mypacts priečinok, ktorý obsahuje štruktúru žiadostí a odpovedí:

{"provider": {"name": "test_provider"}, "consumer": {"name": "test_consumer"}, "interakcie": [{"description": "GET REQUEST", "request": {" method ":" GET "," path ":" / "}," response ": {" status ": 200," headers ": {" Content-Type ":" application / json "}," body ": { "condition": true, "name": "tom"}}, "providerStates": [{"name": "test GET"}]}, {"description": "POST REQUEST", ...}], "metadata": {"pact-specification": {"version": "3.0.0"}, "pact-jvm": {"version": "3.5.0"}}}

5. Testovanie klienta a poskytovateľa pomocou zmluvy

Teraz, keď máme našu zmluvu, môžeme použiť na vytvorenie testov proti nej pre klienta aj poskytovateľa.

Každý z týchto testov bude používať simulovaný model, ktorý vychádza zo zmluvy, čo znamená:

  • klient použije falošného poskytovateľa
  • poskytovateľ použije falošného klienta

Testy sa účinne vykonávajú proti zmluve.

5.1. Testovanie klienta

Po definovaní zmluvy môžeme testovať interakcie so službou, ktorá sa na základe tejto zmluvy vytvorí. Môžeme vytvoriť normálny test JUnit, ale musíme si zapamätať, že @PactVerification anotácia na začiatku testu.

Napíšeme test pre požiadavku GET:

@Test @PactVerification () public void givenGet_whenSendRequest_shouldReturn200WithProperHeaderAndBody () {// when ResponseEntity response = new RestTemplate () .getForEntity (mockProvider.getUrl () + "/ pact", String.class); // potom assertThat (response.getStatusCode (). value ()). isEqualTo (200); assertThat (response.getHeaders (). get ("Content-Type"). contains ("application / json")). isTrue (); assertThat (response.getBody ()). contains ("condition", "true", "name", "tom"); }

The @PactVerification o spustenie služby HTTP sa stará anotácia. V teste nám stačí poslať žiadosť GET a ubezpečiť sa, že naša odpoveď je v súlade so zmluvou.

Pridajme test aj pre volanie metódy POST:

HttpHeaders httpHeaders = nový HttpHeaders (); httpHeaders.setContentType (MediaType.APPLICATION_JSON); Reťazec jsonBody = "{\" meno \ ": \" Michael \ "}"; // when ResponseEntity postResponse = new RestTemplate () .exchange (mockProvider.getUrl () + "/ create", HttpMethod.POST, new HttpEntity (jsonBody, httpHeaders), String.class); // potom assertThat (postResponse.getStatusCode (). value ()). isEqualTo (201);

Ako vidíme, kód odpovede pre požiadavku POST sa rovná 201 - presne tak, ako bol definovaný v Pakt zmluva.

Ako sme používali @PactVerification () anotácia Pakt knižnica spúšťa webový server na základe predtým definovanej zmluvy pred naším testovacím prípadom.

5.2. Testovanie poskytovateľa

Druhým krokom nášho overenia zmluvy je vytvorenie testu pre poskytovateľa, ktorý používa falošného klienta na základe zmluvy.

Implementácia nášho poskytovateľa sa bude riadiť touto zmluvou spôsobom TDD.

Pre náš príklad použijeme Spring Boot REST API.

Najskôr, aby sme vytvorili náš test JUnit, budeme musieť pridať závislosť pact-jvm-provider-junit_2.11:

 test au.com.dius pact-jvm-provider-junit_2.11 3.5.0 

To nám umožňuje vytvoriť test JUnit pomocou PactRunner a zadaním názvu poskytovateľa a umiestnenia artefaktu Paktu:

@RunWith (PactRunner.class) @Provider ("test_provider") @PactFolder ("pacts") verejná trieda PactProviderTest {// ...}

Aby táto konfigurácia fungovala, musíme umiestniť test_consumer-test_provider.json súbor v pakty priečinok nášho projektu služieb REST.

Ďalej definujeme cieľ, ktorý sa má použiť na overenie interakcií v zmluve, a pred spustením testov spustíme aplikáciu Spring Boot:

@TestTarget public final Cieľový cieľ = nový HttpTarget ("http", "localhost", 8082, "/ spring-rest"); súkromná statická aplikácia ConfigurableWebApplicationContext; @BeforeClass public static void start () {application = (ConfigurableWebApplicationContext) SpringApplication.run (MainApplication.class); }

Nakoniec zadáme štáty v zmluve, ktoré chceme testovať:

@State ("test GET") verejné neplatné toGetState () {} @State ("test POST") verejné neplatné toPostState () {}

Spustenie tejto triedy JUnit vykoná dva testy pre dve požiadavky GET a POST. Pozrime sa na protokol:

Overenie dohody medzi test_consumer a test_provider Daný test GET GET REQUEST vráti odpoveď, ktorá má stavový kód 200 (OK) obsahuje hlavičky „Content-Type“ s hodnotou „application / json“ (OK) má zodpovedajúce telo (OK) Overenie paktu medzi test_consumer a test_provider Daný test POST POST REQUEST vráti odpoveď, ktorá má stavový kód 201 (OK) má zodpovedajúce telo (OK)

Upozorňujeme, že sme sem nezahrnuli kód na vytvorenie služby REST. Kompletný servis a test nájdete v projekte GitHub.

6. Záver

V tomto rýchlom výučbe sme sa pozreli na zmluvy riadené spotrebiteľmi.

Zmluvu sme vytvorili pomocou Pakt knižnica. Len čo sme definovali zmluvu, mohli sme klienta a službu otestovať na základe zmluvy a ubezpečiť sa, že vyhovujú špecifikácii.

Implementáciu všetkých týchto príkladov a útržkov kódu nájdete v projekte GitHub - jedná sa o projekt Maven, takže by malo byť ľahké ho importovať a spustiť tak, ako je.


$config[zx-auto] not found$config[zx-overlay] not found