...

Contract Testing

Categorie: Software Engineering | Leestijd: 7 min. | Deel dit artikel

Schrijver: Max van Deursen, Software Engineer

Contract Testing voor consumers: aan de slag met Specmatic’s Smart Mocks

Wanneer je als developer met een API werkt, vertrouw je op de specificatie om te weten hoe je ermee kunt communiceren. In mijn vorige blog liet ik zien hoe je met Specmatic kunt controleren of zowel de consumer als de provider zich aan die afspraken in de OpenAPI Specification (OAS) houden. In deze blog duiken we dieper de praktijk in: ik laat zien hoe je als consumer de Smart Mock-functie van Specmatic inzet om je integratie te testen; nog voordat de echte API bestaat.

Het voorbeeld
Om te laten zien hoe Specmatic werkt, gebruik ik een situatie die veel ontwikkelaars zullen herkennen: het winkelmandje van een webshop. In dit voorbeeld ben jij verantwoordelijk voor de frontend van deze shop. Je kunt een mandje aanmaken, producten toevoegen en de inhoud bekijken. Die logica zit niet lokaal, maar in een externe API en daar ben jij als consumer van afhankelijk. De vraag is dus: hoe weet je zeker dat jouw webshop straks goed met die API kan praten? In dit voorbeeld laat ik zien hoe je dat kunt testen met Specmatic, zonder dat de echte API al beschikbaar is. De code is in TypeScript, omdat dat vaak wordt gebruikt voor frontendlogica. Alles staat op GitHub, zodat je het zelf kunt proberen.

Het contract
Bij het eerste ontwerp van de winkel ga je samen met het API team rond de tafel zitten om de functionaliteit te beschrijven. Hieruit volgt het contract: CartAPI_v1.yaml. Dit contract bevat drie endpoints, die de beoogde functionaliteit ondersteunen:

  • POST /carts: Een endpoint om een nieuw winkelmandje aan te maken. Je geeft het ID van de gebruiker mee, en je krijgt het ID van het winkelmandje terug.
  • POST /carts/{cartId}/items: Een endpoint om een product toe te voegen aan het winkelmandje. Je geeft de ID van het mandje aan en geeft het ID en de hoeveelheid van het product mee die je wilt toevoegen. De API geeft aan of de toevoeging is gelukt.
  • GET /carts/{cartId}: Een endpoint om de inhoud van het winkelmandje op te vragen. Je krijgt de ID van de gebruiker, het winkelmandje, en de lijst van toegevoegde producten met hun hoeveelheden aan de hand van het ID van het winkelmandje.

De OAS beschrijft ook welke verschillende statuscodes kunnen worden teruggegeven. Zo wordt de HTTP statuscode 404 (Not Found) teruggegeven als het winkelmandje voor POST /carts/{cartId}/items niet wordt gevonden.

Jouw code
Om deze API te gebruiken schrijf je als consumer een klasse die met de API interacteert. In het voorbeeld is dat de CartService. Deze klasse regelt de communicatie tussen de API en de rest van de website. Deze service bevat verschillende functies die overeenkomen met de endpoints in het contract. Natuurlijk wil je weten of de CartService naar behoren werkt. Je gebruikt hiervoor automatische tests die alle verschillende situaties in de OAS nabootsen. Deze tests staan in cart-service.spec.ts omschreven. Een belangrijk onderdeel van het functioneren van de CartService is dat de communicatie volgens het opgestelde OAS verloopt. Hier gebruik je natuurlijk Specmatic voor!

Ophalen van een bestaand mandje
Om te testen of de CartService een bestaand mandje kan ophalen en correct teruggeeft, wil je voor een specifiek ID een specifiek mandje teruggeven. Zo kan je kijken of dit mandje correct wordt teruggegeven door de service. Deze situatie kan je met een voorbeeld omschrijven. De map examples/CartAPI_v1 bevat alle voorbeelden die Specmatic gebruikt. Het bestand getCart.success.json binnen deze map bevat het voorbeeld voor het ophalen:
contract testing 1
Hierin staat omschreven dat het mandje met ID 2 van gebruiker 1 is en vier keer het product met ID 3 bevat. Elke keer als je Specmatic voor het mandje met ID 2 vraagt via het endpoint GET /carts/2, zal Specmatic deze specifieke gegevens teruggeven. In de test op regel 24 tot en met 30 wordt het winkelmandje met ID 2 gebruikt om te testen of de CartService inderdaad deze gegevens teruggeeft:
contract testing 2

Toevoegen van een product aan een mandje
De tests controleren ook of de CartService op de juiste manier een product kan toevoegen aan een mandje. De test op regel 36 tot en met 41 verifieert deze functionaliteit door een product met ID 3 toe te voegen aan winkelmandje 2:
contract testing 3
En de test slaagt! Dat verraste mij in eerste instantie; ik had geen voorbeeld geschreven voor deze situatie, maar deze test gaat toch goed. Hoe kan dat nou?
Specmatic bleek de response zelf te genereren op basis van de OAS. Dat was meteen een goede reminder: Specmatic denkt actief met je mee. Als er geen voorbeeld is voor de aanroep, geeft Specmatic  een gegenereerd antwoord terug op basis van het contract. In het geval van POST /carts/2/items geeft Specmatic een leeg antwoord terug met statuscode 201, om aan te geven dat alles goed is ontvangen en verwerkt. Dit gebeurt dus ook in onze test!

Toevoegen van een bestaand product
De specificatie geeft aan dat de foutcode 409 (Conflict) wordt teruggegeven als je een product probeert toe te voegen die al in het mandje zit. Ook deze wil je binnen de CartService afhandelen en dit wil je ook verifiëren. De voorbeelden van Specmatic kunnen ook aangeven welke statuscode wordt teruggegeven. Hierdoor is het proces om deze functionaliteit te testen vergelijkbaar met de test voor het ophalen van een bestaand winkelmandje: maak een voorbeeld en zorg dat je hetzelfde winkelmandje gebruikt in de test. Dit zie je terug in het voorbeeld addItemToCart.conflict.json:
contract testing 4
De test op regel 51 tot en met 56 gebruikt net zoals het voorbeeld het winkelmandje met ID 409:

contract testing 5
Deze testen samen het geval waarin een bestaand product wordt toegevoegd.

Hoe werken de tests samen met Specmatic?
In bovenstaande situaties gaat het steeds over de reactie die Specmatic geeft op een aanroep. Deze reactie gebaseerd op een uitgewerkt voorbeeld of op de OAS. De Smart Mock server van Specmatic moet wel draaien wanneer de testen draaien om deze te doen slagen.

Hiervoor gebruik je de Docker image van Specmatic. Hieraan geef je het contract, de voorbeelden, en de configuratie mee, om aan te geven wat je van Specmatic verwacht. De configuratie omschrijft dat het contract wordt gebruikt door jou als consumer:
contract testing 6
De code geeft het “stub” commando aan de Specmatic Docker container mee, zodat deze als Smart Mock functioneert.

Omdat ik de tests betrouwbaar en geautomatiseerd wil draaien zonder gedoe met het handmatig starten van Specmatic, gebruikt de code Testcontainers. In testcontainers.ts staat de voorbereidende code om de Specmatic container te configureren en op te starten. Deze code wordt uitgevoerd voordat er testen draaien met behulp van vitest. De configuratie van vitest in zorgt ervoor dat dit gebeurt. De tests in cart-service.spec.ts maken gebruik van de Specmatic container’s port, die in regel 5 en 6 wordt opgevraagd en ingezet:
contract testing 7
Met deze opzet wordt de Specmatic container eerst juist geconfigureerd en opgestart. Daarna draaien de tests uit cart-service.spec.ts en wordt de CartService compleet doorgelicht. Zodra de tests zijn voltooid, wordt de Specmatic container door Testcontainers weer weggegooid; deze is nu niet meer nodig. Op deze manier wordt je lokale testomgeving vrijwel net zo betrouwbaar als de live situatie en dat is precies wat je wilt bij contract testing.

Hoe nu verder?
Dit voorbeeld legt de fundering om Specmatic binnen Typescript in te zetten. Specmatic’s documentatie over Service Virtualization biedt een uitgebreide omschrijving van de Smart Mock functionaliteit. Met dit voorbeeld heb je gezien hoe jij als consumer Specmatic kan inzetten om te verifiëren dat jouw code volgens de OAS werkt. Ben je nieuwsgierig hoe Specmatic ook de provider test? In de volgende blog neem ik je mee naar de andere kant, om er zeker van te zijn dat de provider en consumer allebei volgens het contract kunnen communiceren

Overzicht blogreeks
19 augustus 2025 – Contract Testing: Integratieproblemen vroeg opgelost
20 oktober 2025 – Implementeer contract testing als Consumer met Specmatic
23 december 2025 – Valideer je API implementatie met behulp van Specmatic
17 februari 2026 – Beheer van OpenAPI specificaties en veilig wijzigen met Specmatic

Deel dit artikel

Gerelateerde berichten