PageSourceSearch

https://aim-ene.github.io/assets/js/703534a6.e66f3f69.js

js aim-ene.github.io collected 2026-10-03 08:36:09 UTC 8,328 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkaim_ene_github_io=self.webpackChunkaim_ene_github_io||[]).push([[2314],{2408(e,n,t){t.r(n),t.d(n,{assets:()=>d,contentTitle:()=>a,default:()=>c,frontMatter:()=>o,metadata:()=>r,toc:()=>l});const r=JSON.parse('{"id":"week-5/les-3/Lesprogramma/API-testen/index","title":"Spring Boot applicatie testen","description":"Om een Spring boot API (applicatie) met Gherkin scenario\'s te kunnen testen is er de aanvullende uitdaging om vanuit glue code de juiste endpoints aan te kunnen roepen zodat het gedrag (van de API) getest kan worden.","source":"@site/courses/doex/studenten/docs/week-5/les-3/02-Lesprogramma/API-testen/index.mdx","sourceDirName":"week-5/les-3/02-Lesprogramma/API-testen","slug":"/week-5/les-3/Lesprogramma/API-testen/","permalink":"/doex/week-5/les-3/Lesprogramma/API-testen/","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"title":"Spring Boot applicatie testen"},"sidebar":"materialSidebar","previous":{"title":"Lesprogramma","permalink":"/doex/week-5/les-3/Lesprogramma/"},"next":{"title":"JSON parsing met RestAssured","permalink":"/doex/week-5/les-3/Lesprogramma/API-testen/example_JSON"}}');var s=t(74848),i=t(28453);const o={title:"Spring Boot applicatie testen"},a=void 0,d={},l=[{value:"HTTP request",id:"http-request",level:2},{value:"HTTP response",id:"http-response",level:2},{value:"Default API URI en port configuratie",id:"default-api-uri-en-port-configuratie",level:2}];function p(e){const n={a:"a",code:"code",em:"em",h2:"h2",li:"li",ol:"ol",p:"p",pre:"pre",...(0,i.R)(),...e.components};return(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)(n.p,{children:["Om een Spring boot API (applicatie) met ",(0,s.jsx)(n.em,{children:"Gherkin scenario's"})," te kunnen testen is er de aanvullende uitdaging om vanuit glue code de juiste endpoints aan te kunnen roepen zodat het gedrag (van de API) getest kan worden."]}),"\n",(0,s.jsxs)(n.p,{children:["Maak hiervoor bijvoorbeeld gebruik van ",(0,s.jsx)(n.a,{href:"https://rest-assured.io/",children:"RestAssured"})," dat dit mogelijk maakt met een ",(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/Fluent_interface",children:"fluent interface"}),"."]}),"\n",(0,s.jsxs)(n.p,{children:["Voor een wat uitgebreidere introductie op de library zou je ",(0,s.jsx)(n.a,{href:"https://medium.com/@bubu.tripathy/testing-restful-apis-with-rest-assured-6d245401deea",children:"dit artikel"})," kunnen lezen, maar het belangrijkste om te realiseren is dat het testen van een (REST) API meestal bestaat uit twee stappen:"]}),"\n",(0,s.jsxs)(n.ol,{children:["\n",(0,s.jsx)(n.li,{children:"uitvoeren van een HTTP request (GET/POST/UPDATE/DELETE)"}),"\n",(0,s.jsx)(n.li,{children:"afhandelen van de HTTP response (valideren van HTTP status code, valideren van HTTP bericht)"}),"\n"]}),"\n",(0,s.jsx)(n.p,{children:"Hoe je deze handelingen kunt bereiken is hieronder ge\xefllustreerd met wat simpele voorbeelden van een GET- en POST-request."}),"\n",(0,s.jsx)(n.h2,{id:"http-request",children:"HTTP request"}),"\n",(0,s.jsx)(n.p,{children:"Een eenvoudig voorbeeld van een GET-request met RestAssured"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-java",children:'Response response = RestAssured\n    .given()\n    .when()\n        .get("https://api.example.com/users")\n    .then()\n        .extract()\n            .response();\n'})}),"\n",(0,s.jsx)(n.p,{children:"Een eenvoudig voorbeeld van een POST-request inclusief dummy JSON (HTTP body) met RestAssured"}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-java",children:'Response response = RestAssured\n    .given()\n        .contentType(ContentType.JSON)\n        .body("{\\"query\\":\\"test\\"}")\n    .when()\n        .post("https://recipe-food-nutrition15.p.rapidapi.com/recipee-search")\n    .then()\n        .extract()\n            .response();\n'})}),"\n",(0,s.jsx)(n.h2,{id:"http-response",children:"HTTP response"}),"\n",(0,s.jsx)(n.p,{children:"Een HTTP status code kan door RestAssured gecheckt worden voordat de inhoud opgehaald wordt om fouten verderop in de afhandeling te voorkomen.\nDit is simpelweg mogelijk door voordat de functie extract aangeroepen wordt op de interface allereerst de verwachte status code te verifi\xebren."}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-java",children:'Response response = RestAssured\n    .given()\n    .when()\n        .get("https://api.example.com/users")\n    .then()\n        .statusCode(200) // verwachte status code\n        .extract()\n            .response();\n'})}),"\n",(0,s.jsxs)(n.p,{children:["Het resultaat van de ",(0,s.jsx)(n.em,{children:"extract.response"})," is dat er een object is met alle data uit het ontvangen HTTP bericht als antwoord op de request.\nDit response object zou je kunnen opslaan in een variabele van de ",(0,s.jsx)(n.em,{children:"StepDef
1initions.java"})," om tijdens een Cucumber ",(0,s.jsx)(n.em,{children:"@Then"})," stap te verifi\xebren."]}),"\n",(0,s.jsxs)(n.p,{children:["De response kan inhoudelijk gequeried worden met bijvoorbeeld ",(0,s.jsx)(n.em,{children:"JSONPath"})," door deze uit de response te extraheren met de bijbehorende functie.\nVervolgens is het mogelijk om specifieke velden uit de JSON uit te lezen of om te zetten naar objecten middels ",(0,s.jsx)(n.em,{children:"Object Mapping"}),".\nZie de documentatie van ",(0,s.jsx)(n.a,{href:"https://en.wikipedia.org/wiki/JSONPath",children:"JSONPath"}),"\nof gebruik deze ",(0,s.jsx)(n.a,{href:"https://jsonpath.com/",children:"online editor"})," om de juiste queries op te stellen."]}),"\n",(0,s.jsxs)(n.p,{children:["Zie ",(0,s.jsx)(n.a,{href:"/doex/week-5/les-3/Lesprogramma/API-testen/example_JSON",children:"deze pagina voor een voorbeeld"})," met automatische mapping naar een object om een idee te krijgen hoe dit werkt.\nTer illustratie is ook een snippet van de JSON die in de HTTP response terug zou komen opgenomen ter referentie.\nZoals je kunt zien wordt door middel van JSONPath query de JSON data afgewandeld tot de recepten waarvan de velden met JSON annotaties gekoppeld worden aan attributen in het object."]}),"\n",(0,s.jsx)(n.h2,{id:"default-api-uri-en-port-configuratie",children:"Default API URI en port configuratie"}),"\n",(0,s.jsxs)(n.p,{children:["Een aantal instellingen die bij elke HTTP request terugkomt zijn de URI en poort waarop deze benaderd dient te worden.\nHiervoor is een handige annotatie ontwikkeld in het geval deze door Spring Boot opgestart is,\neen variabele geannoteerd met ",(0,s.jsx)(n.em,{children:"@LocalServerPort"})," zal altijd automatisch gevuld worden met de poort van de lokale Spring Boot server."]}),"\n",(0,s.jsx)(n.p,{children:'Aannemende dat de application.properties van de Spring applicatie zo geconfigureerd is om op localhost te draaien, krijg je onderstaande code.\nDie gebruikt kan worden om in een functie een specifiek endpoint van de applicatie onder test (in dit geval "users") aan te roepen.'}),"\n",(0,s.jsx)(n.pre,{children:(0,s.jsx)(n.code,{className:"language-java",children:'@CucumberContextConfiguration\n@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)\n// TODO: moet ook zonder de context na elke test opnieuw op te bouwen kunnen, maar hoe?\n@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)\npublic class StepDefinitions {\n\n    @LocalServerPort\n    private int port;\n\n    @Before\n    public void configureRestAssured() {\n        RestAssured.baseURI = "http://localhost";\n        RestAssured.port = port;\n    }\n\n    private Response exampleAPICall(){\n        return RestAssured\n            .given()\n            .when()\n                .get("/users")\n            .then()\n                .extract()\n                    .response();\n    }\n}\n'})})]})}function c(e={}){const{wrapper:n}={...(0,i.R)(),...e.components};return n?(0,s.jsx)(n,{...e,children:(0,s.jsx)(p,{...e})}):p(e)}},28453(e,n,t){t.d(n,{R:()=>o,x:()=>a});var r=t(96540);const s={},i=r.createContext(s);function o(e){const n=r.useContext(i);return r.useMemo(function(){return"function"==typeof e?e(n):{...n,...e}},[n,e])}function a(e){let n;return n=e.disableParentContext?"function"==typeof e.components?e.components(s):e.components||s:o(e.components),r.createElement(i.Provider,{value:n},e.children)}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.