SlideShare a Scribd company logo
1 of 112
Download to read offline
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
1 z 112 13.06.2016 13:47
/ oms@codearte.io@olga_maciaszek
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
2 z 112 13.06.2016 13:47
1. Introduction
2. Background
3. Solution
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
3 z 112 13.06.2016 13:47
Accurest - Consumer Driven ContractsAccurest - Consumer Driven Contracts
Verifier for REST and MessagingVerifier for REST and Messaging
Easy to write scripts
Works out of the box with Gradle and Maven
Automatically generated WireMock and Messaging stubs
Automatically generated Spock/ JUnit tests
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
4 z 112 13.06.2016 13:47
Tech StackTech Stack
Gradle, Maven
Java, Groovy
REST: Standalone App, MockMvc, JAX-RS
Messaging: Spring Integration, Spring Cloud Stream,
Apache Camel
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
5 z 112 13.06.2016 13:47
MonolithMonolith
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
6 z 112 13.06.2016 13:47
Lengthy and Costly Development Process
Long Testing Times
Long Deployment Times
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
7 z 112 13.06.2016 13:47
MicroservicesMicroservices
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
8 z 112 13.06.2016 13:47
Many smaller services
Each team responsible for its service
REST communication
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
9 z 112 13.06.2016 13:47
New Issues and ChallengesNew Issues and Challenges
Creating and modifying REST contracts
Testing a Microservice-based system
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
10 z 112 13.06.2016 13:47
New Issues and ChallengesNew Issues and Challenges
Creating and modifying REST contracts
Testing a Microservice-based system
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
11 z 112 13.06.2016 13:47
One server + limited clients
vs.
Multiple client/servers communicating with each other
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
12 z 112 13.06.2016 13:47
Defining and modifying REST contracts much more often
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
13 z 112 13.06.2016 13:47
Quick information when the REST contract is modified
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
14 z 112 13.06.2016 13:47
Various clients requesting different changes at the same
time
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
15 z 112 13.06.2016 13:47
RequirementsRequirements
Consumer Driven Contracts
All consumers need to be notified when the Contract has
changed
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
16 z 112 13.06.2016 13:47
New Issues and ChallengesNew Issues and Challenges
Creating and modifying REST contracts
Testing a Microservice-based system
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
17 z 112 13.06.2016 13:47
Monolith E2E TestsMonolith E2E Tests
Comprehensive
Verified borders
Considerably improved safety
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
18 z 112 13.06.2016 13:47
1 to rule them all1 to rule them all
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
19 z 112 13.06.2016 13:47
Against the very idea of microservices!Against the very idea of microservices!
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
20 z 112 13.06.2016 13:47
1 pipeline per service, all the1 pipeline per service, all the
collaborators addedcollaborators added
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
21 z 112 13.06.2016 13:47
Too costly!Too costly!
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
22 z 112 13.06.2016 13:47
Stubbed collaboratorsStubbed collaborators
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
23 z 112 13.06.2016 13:47
Stubs get corrodedStubs get corroded
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
24 z 112 13.06.2016 13:47
RequirementsRequirements
Stubs required
Validating stubs against servers required
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
25 z 112 13.06.2016 13:47
RequirementsRequirements
Consumer Driven Contracts
All consumers need to be notified when the Contract has
changed
Stubs required
Validating stubs against servers required
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
26 z 112 13.06.2016 13:47
AccurestAccurest
Scripts that define the REST contracts are submitted as PRs
by the client teams
Scripts are used to generate both WireMock stubs and
server tests
New server version along the new stubs only published
when server tests have passed
Client services download server stubs and use them for
tests
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
27 z 112 13.06.2016 13:47
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
28 z 112 13.06.2016 13:47
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
29 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make
request {
method 'PUT'
url '/fraudcheck'
body(
clientId: "12345678902",
loanAmount: 99999
)
headers {
header('Content-Type', 'application/vnd.fraud.v1+json')
}
}
response {
status 200
body(
fraudCheckStatus: "FRAUD",
rejectionReason: "Amount too high"
)
headers {
header('Content-Type': 'application/vnd.fraud.v1+json')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
30 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make
request {
method 'PUT'
url '/fraudcheck'
body(
clientId: "12345678902",
loanAmount: 99999
)
headers {
header('Content-Type', 'application/vnd.fraud.v1+json')
}
}
response {
status 200
body(
fraudCheckStatus: "FRAUD",
rejectionReason: "Amount too high"
)
headers {
header('Content-Type': 'application/vnd.fraud.v1+json')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
31 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make
request {
method 'PUT'
url '/fraudcheck'
body(
clientId: "12345678902",
loanAmount: 99999
)
headers {
header('Content-Type', 'application/vnd.fraud.v1+json')
}
}
response {
status 200
body(
fraudCheckStatus: "FRAUD",
rejectionReason: "Amount too high"
)
headers {
header('Content-Type': 'application/vnd.fraud.v1+json')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
32 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make
request {
method 'PUT'
url '/fraudcheck'
body(
clientId: "12345678902",
loanAmount: 99999
)
headers {
header('Content-Type', 'application/vnd.fraud.v1+json')
}
}
response {
status 200
body(
fraudCheckStatus: "FRAUD",
rejectionReason: "Amount too high"
)
headers {
header('Content-Type': 'application/vnd.fraud.v1+json')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
33 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make
request {
method 'PUT'
url '/fraudcheck'
body(
clientId: "12345678902",
loanAmount: 99999
)
headers {
header('Content-Type', 'application/vnd.fraud.v1+json')
}
}
response {
status 200
body(
fraudCheckStatus: "FRAUD",
rejectionReason: "Amount too high"
)
headers {
header('Content-Type': 'application/vnd.fraud.v1+json')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
34 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make
request {
method 'PUT'
url '/fraudcheck'
body(
clientId: "12345678902",
loanAmount: 99999
)
headers {
header('Content-Type', 'application/vnd.fraud.v1+json')
}
}
response {
status 200
body(
fraudCheckStatus: "FRAUD",
rejectionReason: "Amount too high"
)
headers {
header('Content-Type': 'application/vnd.fraud.v1+json')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
35 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make
request {
method 'PUT'
url '/fraudcheck'
body(
clientId: "12345678902",
loanAmount: 99999
)
headers {
header('Content-Type', 'application/vnd.fraud.v1+json')
}
}
response {
status 200
body(
fraudCheckStatus: "FRAUD",
rejectionReason: "Amount too high"
)
headers {
header('Content-Type': 'application/vnd.fraud.v1+json')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
36 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make
request {
method 'PUT'
url '/fraudcheck'
body(
clientId: "12345678902",
loanAmount: 99999
)
headers {
header('Content-Type', 'application/vnd.fraud.v1+json')
}
}
response {
status 200
body(
fraudCheckStatus: "FRAUD",
rejectionReason: "Amount too high"
)
headers {
header('Content-Type': 'application/vnd.fraud.v1+json')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
37 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make
request {
method 'PUT'
url '/fraudcheck'
body(
clientId: "12345678902",
loanAmount: 99999
)
headers {
header('Content-Type', 'application/vnd.fraud.v1+json')
}
}
response {
status 200
body(
fraudCheckStatus: "FRAUD",
rejectionReason: "Amount too high"
)
headers {
header('Content-Type': 'application/vnd.fraud.v1+json')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
38 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make
request {
method 'PUT'
url '/fraudcheck'
body(
clientId: "12345678902",
loanAmount: 99999
)
headers {
header('Content-Type', 'application/vnd.fraud.v1+json')
}
}
response {
status 200
body(
fraudCheckStatus: "FRAUD",
rejectionReason: "Amount too high"
)
headers {
header('Content-Type': 'application/vnd.fraud.v1+json')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
39 z 112 13.06.2016 13:47
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
40 z 112 13.06.2016 13:47
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
41 z 112 13.06.2016 13:47
WireMockWireMock
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
42 z 112 13.06.2016 13:47
{
"request" : {
"url" : "/fraudcheck",
"method" : "PUT",
"bodyPatterns" : [ {
"matchesJsonPath" : "$[?(@.loanAmount == 99999)]"
}, {
"matchesJsonPath" : "$[?(@.clientId == '12345678902')]"
} ],
"headers" : {
"Content-Type" : {
"equalTo" : "application/vnd.fraud.v1+json"
}
}
},
"response" : {
"status" : 200,
"body" : "{"fraudCheckStatus":"FRAUD",
"rejectionReason":"Amount too high"}",
"headers" : {
"Content-Type" : "application/vnd.fraud.v1+json"
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
43 z 112 13.06.2016 13:47
{
"request" : {
"url" : "/fraudcheck",
"method" : "PUT",
"bodyPatterns" : [ {
"matchesJsonPath" : "$[?(@.loanAmount == 99999)]"
}, {
"matchesJsonPath" : "$[?(@.clientId == '12345678902')]"
} ],
"headers" : {
"Content-Type" : {
"equalTo" : "application/vnd.fraud.v1+json"
}
}
} ,
"response" : {
"status" : 200,
"body" : "{"fraudCheckStatus":"FRAUD",
"rejectionReason":"Amount too high"}",
"headers" : {
"Content-Type" : "application/vnd.fraud.v1+json"
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
44 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make
request {
method 'PUT'
url '/fraudcheck'
body(
clientId: "12345678902",
loanAmount: 99999
)
headers {
header('Content-Type', 'application/vnd.fraud.v1+json')
}
}
response {
status 200
body(
fraudCheckStatus: "FRAUD",
rejectionReason: "Amount too high"
)
headers {
header('Content-Type': 'application/vnd.fraud.v1+json')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
45 z 112 13.06.2016 13:47
{
"request" : {
"url" : "/fraudcheck",
"method" : "PUT",
"bodyPatterns" : [ {
"matchesJsonPath" : "$[?(@.loanAmount == 99999)]"
}, {
"matchesJsonPath" : "$[?(@.clientId == '12345678902')]"
} ],
"headers" : {
"Content-Type" : {
"equalTo" : "application/vnd.fraud.v1+json"
}
}
},
"response" : {
"status" : 200,
"body" : "{"fraudCheckStatus":"FRAUD",
"rejectionReason":"Amount too high"}",
"headers" : {
"Content-Type" : "application/vnd.fraud.v1+json"
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
46 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make
request {
method 'PUT'
url '/fraudcheck'
body(
clientId: "12345678902",
loanAmount: 99999
)
headers {
header('Content-Type', 'application/vnd.fraud.v1+json')
}
}
response {
status 200
body(
fraudCheckStatus: "FRAUD",
rejectionReason: "Amount too high"
)
headers {
header('Content-Type': 'application/vnd.fraud.v1+json')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
47 z 112 13.06.2016 13:47
{
"request" : {
"url" : "/fraudcheck",
"method" : "PUT",
"bodyPatterns" : [ {
"matchesJsonPath" : "$[?(@.loanAmount == 99999)]"
}, {
"matchesJsonPath" : "$[?(@.clientId == '12345678902')]"
} ],
"headers" : {
"Content-Type" : {
"equalTo" : "application/vnd.fraud.v1+json"
}
}
},
"response" : {
"status" : 200,
"body" : "{"fraudCheckStatus":"FRAUD",
"rejectionReason":"Amount too high"}",
"headers" : {
"Content-Type" : "application/vnd.fraud.v1+json"
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
48 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make
request {
method 'PUT'
url '/fraudcheck'
body(
clientId: "12345678902",
loanAmount: 99999
)
headers {
header('Content-Type', 'application/vnd.fraud.v1+json')
}
}
response {
status 200
body(
fraudCheckStatus: "FRAUD",
rejectionReason: "Amount too high"
)
headers {
header('Content-Type': 'application/vnd.fraud.v1+json')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
49 z 112 13.06.2016 13:47
{
"request" : {
"url" : "/fraudcheck",
"method" : "PUT",
"bodyPatterns" : [ {
"matchesJsonPath" : "$[?(@.loanAmount == 99999)]"
}, {
"matchesJsonPath" : "$[?(@.clientId == '12345678902')]"
} ],
"headers" : {
"Content-Type" : {
"equalTo" : "application/vnd.fraud.v1+json"
}
}
},
"response" : {
"status" : 200,
"body" : "{"fraudCheckStatus":"FRAUD",
"rejectionReason":"Amount too high"}",
"headers" : {
"Content-Type" : "application/vnd.fraud.v1+json"
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
50 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make
request {
method 'PUT'
url '/fraudcheck'
body(
clientId: "12345678902",
loanAmount: 99999
)
headers {
header('Content-Type', 'application/vnd.fraud.v1+json')
}
}
response {
status 200
body(
fraudCheckStatus: "FRAUD",
rejectionReason: "Amount too high"
)
headers {
header('Content-Type': 'application/vnd.fraud.v1+json')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
51 z 112 13.06.2016 13:47
{
"request" : {
"url" : "/fraudcheck",
"method" : "PUT",
"bodyPatterns" : [ {
"matchesJsonPath" : "$[?(@.loanAmount == 99999)]"
}, {
"matchesJsonPath" : "$[?(@.clientId == '12345678902')]"
} ],
"headers" : {
"Content-Type" : {
"equalTo" : "application/vnd.fraud.v1+json"
}
}
},
"response" : {
"status" : 200,
"body" : "{"fraudCheckStatus":"FRAUD",
"rejectionReason":"Amount too high"}",
"headers" : {
"Content-Type" : "application/vnd.fraud.v1+json"
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
52 z 112 13.06.2016 13:47
{
"request" : {
"url" : "/fraudcheck",
"method" : "PUT",
"bodyPatterns" : [ {
"matchesJsonPath" : "$[?(@.loanAmount == 99999)]"
}, {
"matchesJsonPath" : "$[?(@.clientId == '12345678902')]"
} ],
"headers" : {
"Content-Type" : {
"equalTo" : "application/vnd.fraud.v1+json"
}
}
},
"response" : {
"status" : 200,
"body" : "{"fraudCheckStatus":"FRAUD",
"rejectionReason":"Amount too high"}",
"headers" : {
"Content-Type" : "application/vnd.fraud.v1+json"
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
53 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make
request {
method 'PUT'
url '/fraudcheck'
body(
clientId: "12345678902",
loanAmount: 99999
)
headers {
header('Content-Type', 'application/vnd.fraud.v1+json')
}
}
response {
status 200
body(
fraudCheckStatus: "FRAUD",
rejectionReason: "Amount too high"
)
headers {
header('Content-Type': 'application/vnd.fraud.v1+json')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
54 z 112 13.06.2016 13:47
{
"request" : {
"url" : "/fraudcheck",
"method" : "PUT",
"bodyPatterns" : [ {
"matchesJsonPath" : "$[?(@.loanAmount == 99999)]"
}, {
"matchesJsonPath" : "$[?(@.clientId == '12345678902')]"
} ],
"headers" : {
"Content-Type" : {
"equalTo" : "application/vnd.fraud.v1+json"
}
}
},
"response" : {
"status" : 200,
"body" : "{"fraudCheckStatus":"FRAUD",
"rejectionReason":"Amount too high"}",
"headers" : {
"Content-Type" : "application/vnd.fraud.v1+json"
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
55 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make
request {
method 'PUT'
url '/fraudcheck'
body(
clientId: "12345678902",
loanAmount: 99999
)
headers {
header('Content-Type', 'application/vnd.fraud.v1+json')
}
}
response {
status 200
body(
fraudCheckStatus: "FRAUD",
rejectionReason: "Amount too high"
)
headers {
header('Content-Type': 'application/vnd.fraud.v1+json')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
56 z 112 13.06.2016 13:47
{
"request" : {
"url" : "/fraudcheck",
"method" : "PUT",
"bodyPatterns" : [ {
"matchesJsonPath" : "$[?(@.loanAmount == 99999)]"
}, {
"matchesJsonPath" : "$[?(@.clientId == '12345678902')]"
} ],
"headers" : {
"Content-Type" : {
"equalTo" : "application/vnd.fraud.v1+json"
}
}
},
"response" : {
"status" : 200,
"body" : "{"fraudCheckStatus":"FRAUD",
"rejectionReason":"Amount too high"}",
"headers" : {
"Content-Type" : "application/vnd.fraud.v1+json"
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
57 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make
request {
method 'PUT'
url '/fraudcheck'
body(
clientId: "12345678902",
loanAmount: 99999
)
headers {
header('Content-Type', 'application/vnd.fraud.v1+json')
}
}
response {
status 200
body(
fraudCheckStatus: "FRAUD",
rejectionReason: "Amount too high"
)
headers {
header('Content-Type': 'application/vnd.fraud.v1+json')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
58 z 112 13.06.2016 13:47
{
"request" : {
"url" : "/fraudcheck",
"method" : "PUT",
"bodyPatterns" : [ {
"matchesJsonPath" : "$[?(@.loanAmount == 99999)]"
}, {
"matchesJsonPath" : "$[?(@.clientId == '12345678902')]"
} ],
"headers" : {
"Content-Type" : {
"equalTo" : "application/vnd.fraud.v1+json"
}
}
},
"response" : {
"status" : 200,
"body" : "{"fraudCheckStatus":"FRAUD",
"rejectionReason":"Amount too high"}",
"headers" : {
"Content-Type" : "application/vnd.fraud.v1+json"
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
59 z 112 13.06.2016 13:47
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
60 z 112 13.06.2016 13:47
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
61 z 112 13.06.2016 13:47
def validate_shouldMarkClientAsFraud() {
given:
def request = given()
.header('Content-Type', 'application/vnd.fraud.v1+json')
.body('{"clientId":"12345678902","loanAmount":99999}')
when:
def response = given().spec(request).put("/fraudcheck")
then:
response.statusCode == 200
response.header('Content-Type') == 'application/vnd.fraud.v1+json'
and:
DocumentContext parsedJson = JsonPath.parse(response.body.asString())
assertTassertThatJson(parsedJson).field("rejectionReason")
.isEqualTo("Amount too high")
assertThatJson(parsedJson).field("fraudCheckStatus").isEqualTo("FRAUD")
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
62 z 112 13.06.2016 13:47
com.jayway.RestAssured
com.toomuchcoding.jsonassert
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
63 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make
request {
method 'PUT'
url '/fraudcheck'
body(
clientId: "12345678902",
loanAmount: 99999
)
headers {
header('Content-Type', 'application/vnd.fraud.v1+json')
}
}
response {
status 200
body(
fraudCheckStatus: "FRAUD",
rejectionReason: "Amount too high"
)
headers {
header('Content-Type': 'application/vnd.fraud.v1+json')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
64 z 112 13.06.2016 13:47
def validate_shouldMarkClientAsFraud() {
given:
def request = given()
.header('Content-Type', 'application/vnd.fraud.v1+json')
.body('{"clientId":"12345678902","loanAmount":99999}')
when:
def response = given().spec(request).put("/fraudcheck")
then:
response.statusCode == 200
response.header('Content-Type') == 'application/vnd.fraud.v1+json'
and:
DocumentContext parsedJson = JsonPath.parse(response.body.asString())
assertTassertThatJson(parsedJson).field("rejectionReason")
.isEqualTo("Amount too high")
assertThatJson(parsedJson).field("fraudCheckStatus").isEqualTo("FRAUD")
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
65 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make
request {
method 'PUT'
url '/fraudcheck'
body(
clientId: "12345678902",
loanAmount: 99999
)
headers {
header('Content-Type', 'application/vnd.fraud.v1+json')
}
}
response {
status 200
body(
fraudCheckStatus: "FRAUD",
rejectionReason: "Amount too high"
)
headers {
header('Content-Type': 'application/vnd.fraud.v1+json')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
66 z 112 13.06.2016 13:47
def validate_shouldMarkClientAsFraud() {
given:
def request = given()
.header('Content-Type', 'application/vnd.fraud.v1+json')
.body('{"clientId":"12345678902","loanAmount":99999}')
when:
def response = given().spec(request).put("/fraudcheck")
then:
response.statusCode == 200
response.header('Content-Type') == 'application/vnd.fraud.v1+json'
and:
DocumentContext parsedJson = JsonPath.parse(response.body.asString())
assertThatJson(parsedJson).field("rejectionReason")
.isEqualTo("Amount too high")
assertThatJson(parsedJson).field("fraudCheckStatus").isEqualTo("FRAUD")
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
67 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make
request {
method 'PUT'
url '/fraudcheck'
body(
clientId: "12345678902",
loanAmount: 99999
)
headers {
header('Content-Type', 'application/vnd.fraud.v1+json')
}
}
response {
status 200
body(
fraudCheckStatus: "FRAUD",
rejectionReason: "Amount too high"
)
headers {
header('Content-Type': 'application/vnd.fraud.v1+json')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
68 z 112 13.06.2016 13:47
def validate_shouldMarkClientAsFraud() {
given:
def request = given()
.header('Content-Type', 'application/vnd.fraud.v1+json')
.body('{"clientId":"12345678902","loanAmount":99999}')
when:
def response = given().spec(request).put("/fraudcheck")
then:
response.statusCode == 200
response.header('Content-Type') == 'application/vnd.fraud.v1+json'
and:
DocumentContext parsedJson = JsonPath.parse(response.body.asString())
assertThatJson(parsedJson).field("rejectionReason")
.isEqualTo("Amount too high")
assertThatJson(parsedJson).field("fraudCheckStatus").isEqualTo("FRAUD")
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
69 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make
request {
method 'PUT'
url '/fraudcheck'
body(
clientId: "12345678902",
loanAmount: 99999
)
headers {
header('Content-Type', 'application/vnd.fraud.v1+json')
}
}
response {
status 200
body(
fraudCheckStatus: "FRAUD",
rejectionReason: "Amount too high"
)
headers {
header('Content-Type': 'application/vnd.fraud.v1+json')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
70 z 112 13.06.2016 13:47
def validate_shouldMarkClientAsFraud() {
given:
def request = given()
.header('Content-Type', 'application/vnd.fraud.v1+json')
.body('{"clientId":"12345678902","loanAmount":99999}')
when:
def response = given().spec(request).put("/fraudcheck")
then:
response.statusCode == 200
response.header('Content-Type') == 'application/vnd.fraud.v1+json'
and:
DocumentContext parsedJson = JsonPath.parse(response.body.asString())
assertThatJson(parsedJson).field("rejectionReason")
.isEqualTo("Amount too high")
assertThatJson(parsedJson).field("fraudCheckStatus").isEqualTo("FRAUD")
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
71 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make
request {
method 'PUT'
url '/fraudcheck'
body(
clientId: "12345678902",
loanAmount: 99999
)
headers {
header('Content-Type', 'application/vnd.fraud.v1+json')
}
}
response {
status 200
body(
fraudCheckStatus: "FRAUD",
rejectionReason: "Amount too high"
)
headers {
header('Content-Type': 'application/vnd.fraud.v1+json')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
72 z 112 13.06.2016 13:47
def validate_shouldMarkClientAsFraud() {
given:
def request = given()
.header('Content-Type', 'application/vnd.fraud.v1+json')
.body('{"clientId":"12345678902","loanAmount":99999}')
when:
def response = given().spec(request).put("/fraudcheck")
then:
response.statusCode == 200
response.header('Content-Type') == 'application/vnd.fraud.v1+json'
and:
DocumentContext parsedJson = JsonPath.parse(response.body.asString())
assertThatJson(parsedJson).field("rejectionReason")
.isEqualTo("Amount too high")
assertThatJson(parsedJson).field("fraudCheckStatus").isEqualTo("FRAUD")
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
73 z 112 13.06.2016 13:47
Base Test ClassBase Test Class
class BaseMockMvcSpec extends Specification {
def setup() {
RestAssuredMockMvc.standaloneSetup(new PairIdController())
}
}
@ContextConfiguration(classes = [PaymentResourceStubContext,
ClientResourceStubContext],
loader = SpringApplicationContextLoader)
@WebIntegrationTest
class BaseAccurestSpec extends Specification {
@Autowired
ApplicationContext context
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
74 z 112 13.06.2016 13:47
Regular Expression SupportRegular Expression Support
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
75 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make
request {
method 'PUT'
url '/fraudcheck'
body(
clientId: value(stub(regex('[0-9]{11}')), test("12345678902")),
loanAmount: 99999
)
headers {
header('Content-Type', 'application/vnd.fraud.v1+json')
}
}
response {
status 200
body(
fraudCheckStatus: "FRAUD",
rejectionReason: "Amount too high"
)
headers {
header('Content-Type': 'application/vnd.fraud.v1+json')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
76 z 112 13.06.2016 13:47
{
"request" : {
"url" : "/fraudcheck",
"method" : "PUT",
"bodyPatterns" : [ {
"matchesJsonPath" : "$[?(@.loanAmount == 99999)]"
}, {
"matchesJsonPath" : "$[?(@.clientId =~ /[0-9]{11}/)]"
} ],
"headers" : {
"Content-Type" : {
"equalTo" : "application/vnd.fraud.v1+json"
}
}
},
"response" : {
"status" : 200,
"body" : "{"fraudCheckStatus":"FRAUD",
"rejectionReason":"Amount too high"}",
"headers" : {
"Content-Type" : "application/vnd.fraud.v1+json"
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
77 z 112 13.06.2016 13:47
def validate_shouldMarkClientAsFraud() {
given:
def request = given()
.header('Content-Type', 'application/vnd.fraud.v1+json')
.body('{"clientId":"12345678902" ,"loanAmount":99999}')
when:
def response = given().spec(request).put("/fraudcheck")
then:
response.statusCode == 200
response.header('Content-Type') == 'application/vnd.fraud.v1+json'
and:
DocumentContext parsedJson = JsonPath.parse(response.body.asString())
assertThatJson(parsedJson).field("rejectionReason")
.isEqualTo("Amount too high")
assertThatJson(parsedJson).field("fraudCheckStatus").isEqualTo("FRAUD")
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
78 z 112 13.06.2016 13:47
Executing Custom Methods on theExecuting Custom Methods on the
ServerServer
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
79 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make
request {
method 'PUT'
url '/fraudcheck'
body(
clientId: "12345678902",
loanAmount: 99999
)
headers {
header('Content-Type', 'application/vnd.fraud.v1+json')
}
}
response {
status 200
body(fraudCheckStatus: "FRAUD",
rejectionReason: value(stub("Amount too high"),
test(execute('isCorrectRejectionReason($it)'))))
headers {
header('Content-Type': 'application/vnd.fraud.v1+json')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
80 z 112 13.06.2016 13:47
abstract class BaseMockMvcSpec extends Specification {
def setup() {
RestAssuredMockMvc.standaloneSetup(new FraudDetectionController())
}
void isCorrectRejectionReason(String rejectionReason) {
assert rejectionReason == 'Amount too high'
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
81 z 112 13.06.2016 13:47
def validate_shouldMarkClientAsFraud() {
given:
def request = given()
.header('Content-Type', 'application/vnd.fraud.v1+json')
.body('{"clientId":"12345678902","loanAmount":99999}')
when:
def response = given().spec(request).put("/fraudcheck")
then:
response.statusCode == 200
response.header('Content-Type') == 'application/vnd.fraud.v1+json'
and:
DocumentContext parsedJson = JsonPath.parse(response.body.asString())
assertThatJson(parsedJson).field("fraudCheckStatus").isEqualTo("FRAUD")
isCorrectRejectionReason(parsedJson.read('$.rejectionReason'))
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
82 z 112 13.06.2016 13:47
DSL - Other Available FunctionalitiesDSL - Other Available Functionalities
Query Parameters
Optional Fields
Nested Elements
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
83 z 112 13.06.2016 13:47
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
84 z 112 13.06.2016 13:47
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
85 z 112 13.06.2016 13:47
Stubs published as jars to theStubs published as jars to the
repositoryrepository
Jar, archive
Maven Publish Plugin
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
86 z 112 13.06.2016 13:47
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
87 z 112 13.06.2016 13:47
StubRunnerStubRunner
Automated stubs download from the repository
Automated launching of WireMock server instances and
mounting the stubs
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
88 z 112 13.06.2016 13:47
StubRunner DependenciesStubRunner Dependencies
dependencies {
testCompile 'io.codearte.accurest:stub-runner:1.1.0-M7'
testCompile 'io.codearte.accurest:stub-runner-junit:1.1.0-M7'
testCompile 'io.codearte.accurest:stub-runner-spring:1.1.0-M7'
testCompile 'io.codearte.accurest:stub-runner-spring-cloud:1.1.0-M7'
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
89 z 112 13.06.2016 13:47
Accurest JUnit RuleAccurest JUnit Rule
@ClassRule
@Shared
AccurestRule accurestRule = new AccurestRule().repoRoot('http://www.myrepo.com')
.minPort(11000).maxPort(12000) [ || .withPort(8090)]
.downloadStub('com.toomuchcoding:fraudDetectionService')
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
90 z 112 13.06.2016 13:47
Out of the box support for Spring andOut of the box support for Spring and
SpringCloudSpringCloud
StubRunnerConfiguration
@Autowired StubFinder
StubRunnerDiscoveryClient
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
91 z 112 13.06.2016 13:47
MessagingMessaging
Automated testing of messages created by the producer
Producer's messages automatically provided for consumer
tests by StubRunner
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
92 z 112 13.06.2016 13:47
Producer SideProducer Side
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
93 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make {
description 'Some Description'
label 'some_label'
input {
messageFrom('input')
messageBody([
bookName: 'foo'
])
messageHeaders {
header('sample', 'header')
}
}
outputMessage {
sentTo('output')
body([
bookName: 'foo'
])
headers {
header('BOOK-NAME', 'foo')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
94 z 112 13.06.2016 13:47
def validate_shouldMakeMessageTest() throws Exception {
given:
def inputMessage = accurestMessaging.create('''{"bookName":"foo"}'''
,[
'sample': 'header'
])
when:
accurestMessaging.send(inputMessage, 'input')
then:
def response = accurestMessaging.receiveMessage('output')
assert response != null
response.getHeader('BOOK-NAME') == 'foo'
and:
DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper
.writeValueAsString(response.payload))
assertThatJson(parsedJson).field("bookName").isEqualTo("foo")
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
95 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make {
description 'Some Description'
label 'some_label'
input {
messageFrom('input')
messageBody([
bookName: 'foo'
])
messageHeaders {
header('sample', 'header')
}
}
outputMessage {
sentTo('output')
body([
bookName: 'foo
])
headers {
header('BOOK-NAME', 'foo')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
96 z 112 13.06.2016 13:47
def validate_shouldMakeMessageTest() throws Exception {
given:
def inputMessage = accurestMessaging.create('''{"bookName":"foo"}'''
,[
'sample': 'header'
])
when:
accurestMessaging.send(inputMessage, 'input')
then:
def response = accurestMessaging.receiveMessage('output')
assert response != null
response.getHeader('BOOK-NAME') == 'foo'
and:
DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper
.writeValueAsString(response.payload))
assertThatJson(parsedJson).field("bookName").isEqualTo("foo")
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
97 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make {
description 'Some Description'
label 'some_label'
input {
messageFrom('input')
messageBody([
bookName: 'foo'
])
messageHeaders {
header('sample', 'header')
}
}
outputMessage {
sentTo('output')
body([
bookName: 'foo
])
headers {
header('BOOK-NAME', 'foo')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
98 z 112 13.06.2016 13:47
def validate_shouldMakeMessageTest() throws Exception {
given:
def inputMessage = accurestMessaging.create('''{"bookName":"foo"}'''
,[
'sample': 'header'
])
when:
accurestMessaging.send(inputMessage, 'input')
then:
def response = accurestMessaging.receiveMessage('output')
assert response != null
response.getHeader('BOOK-NAME') == 'foo'
and:
DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper
.writeValueAsString(response.payload))
assertThatJson(parsedJson).field("bookName").isEqualTo("foo")
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
99 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make {
description 'Some Description'
label 'some_label'
input {
messageFrom('input')
messageBody([
bookName: 'foo'
])
messageHeaders {
header('sample', 'header')
}
}
outputMessage {
sentTo('output')
body([
bookName: 'foo
])
headers {
header('BOOK-NAME', 'foo')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
100 z 112 13.06.2016 13:47
def validate_shouldMakeMessageTest() throws Exception {
given:
def inputMessage = accurestMessaging.create('''{"bookName":"foo"}'''
,[
'sample': 'header'
])
when:
accurestMessaging.send(inputMessage, 'input')
then:
def response = accurestMessaging.receiveMessage('output')
assert response != null
response.getHeader('BOOK-NAME') == 'foo'
and:
DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper
.writeValueAsString(response.payload))
assertThatJson(parsedJson).field("bookName").isEqualTo("foo")
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
101 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make {
description 'Some Description'
label 'some_label'
input {
messageFrom('input')
messageBody([
bookName: 'foo'
])
messageHeaders {
header('sample', 'header')
}
}
outputMessage {
sentTo('output')
body([
bookName: 'foo
])
headers {
header('BOOK-NAME', 'foo')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
102 z 112 13.06.2016 13:47
def validate_shouldMakeMessageTest() throws Exception {
given:
def inputMessage = accurestMessaging.create('''{"bookName":"foo"}'''>
,[
'sample': 'header'
])
when:
accurestMessaging.send(inputMessage,'input')
then:
def response = accurestMessaging.receiveMessage('output')
assert response != null
response.getHeader('BOOK-NAME') == 'foo'
and:
DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper
.writeValueAsString(response.payload))
assertThatJson(parsedJson).field("bookName").isEqualTo("foo")
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
103 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make {
description 'Some Description'
label 'some_label'
input {
messageFrom('input')
messageBody([
bookName: 'foo'
])
messageHeaders {
header('sample', 'header')
}
}
outputMessage {
sentTo('output')
body([
bookName: 'foo
])
headers {
header('BOOK-NAME', 'foo')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
104 z 112 13.06.2016 13:47
def validate_shouldMakeMessageTest() throws Exception {
given:
def inputMessage = accurestMessaging.create('''{"bookName":"foo"}'''>
,[
'sample': 'header'
])
when:
accurestMessaging.send(inputMessage,'input')
then:
def response = accurestMessaging.receiveMessage('output')
assert response != null
response.getHeader('BOOK-NAME') == 'foo'
and:
DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper
.writeValueAsString(response.payload))
assertThatJson(parsedJson).field("bookName").isEqualTo("foo")
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
105 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make {
description 'Some Description'
label 'some_label'
input {
messageFrom('input')
messageBody([
bookName: 'foo'
])
messageHeaders {
header('sample', 'header')
}
}
outputMessage {
sentTo('output')
body([
bookName: 'foo
])
headers {
header('BOOK-NAME', 'foo')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
106 z 112 13.06.2016 13:47
def validate_shouldMakeMessageTest() throws Exception {
given:
def inputMessage = accurestMessaging.create('''{"bookName":"foo"}'''>
,[
'sample': 'header'
])
when:
accurestMessaging.send(inputMessage,'input')
then:
def response = accurestMessaging.receiveMessage('output')
assert response != null
response.getHeader('BOOK-NAME') == 'foo'
and:
DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper
.writeValueAsString(response.payload))
assertThatJson(parsedJson).field("bookName").isEqualTo("foo")
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
107 z 112 13.06.2016 13:47
io.codearte.accurest.dsl.Accurest.make {
description 'Some description'
label 'some_label'
input {
triggeredBy('bookReturnedTriggered()')
}
outputMessage {
sentTo('output')
body('''{ "bookName" : "foo" }''')
headers {
header('BOOK-NAME', 'foo')
}
}
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
108 z 112 13.06.2016 13:47
def validate_shouldMakeMessageTest() throws Exception {
when:
bookReturnedTriggered()
then:
def response = accurestMessaging.receiveMessage('output')
assert response != null
response.getHeader('BOOK-NAME') == 'foo'
and:
DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper
.writeValueAsString(response.payload))
assertThatJson(parsedJson).field("bookName").isEqualTo("foo")
}
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
109 z 112 13.06.2016 13:47
Consumer SideConsumer Side
testCompile "io. codearte.accurest:accurest-messaging-camel:${accurestVersion}"
testCompile "io.codearte.accurest:accurest-messaging-integration:${accurestVersion}"
testCompile "io.codearte.accurest:accurest-messaging-stream:${accurestVersion}"
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
110 z 112 13.06.2016 13:47
Possible IssuesPossible Issues
Complex Systems
Test Base Class
Gradle Setup
Young solution
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
111 z 112 13.06.2016 13:47
/ /
Thank youThank you
https://github.com/Codearte/accurest
branch:
08_publish_stubs
https://github.com/OlgaMaciaszek/cdc_examples
branch: 02_with_accurest_rule
https://github.com/OlgaMaciaszek
/LoanApplicationService
Olga Maciaszek-Sharma @olga_maciaszek
oms@codearte.io
Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/
112 z 112 13.06.2016 13:47

More Related Content

Similar to Creating and testing REST contracts with Accurest Gradle

Encode x NEAR: Technical Overview of NEAR 1
Encode x NEAR: Technical Overview of NEAR 1Encode x NEAR: Technical Overview of NEAR 1
Encode x NEAR: Technical Overview of NEAR 1
KlaraOrban
 
ITCamp 2011 - Florin Cardasim - Duplex Communications with WCF and Azure
ITCamp 2011 - Florin Cardasim - Duplex Communications with WCF and AzureITCamp 2011 - Florin Cardasim - Duplex Communications with WCF and Azure
ITCamp 2011 - Florin Cardasim - Duplex Communications with WCF and Azure
Florin Cardasim
 

Similar to Creating and testing REST contracts with Accurest Gradle (20)

Microsoft Windows Azure - Developer’s Guide Access Control in the Windows Azu...
Microsoft Windows Azure - Developer’s Guide Access Control in the Windows Azu...Microsoft Windows Azure - Developer’s Guide Access Control in the Windows Azu...
Microsoft Windows Azure - Developer’s Guide Access Control in the Windows Azu...
 
An In-Depth Comparison of WebSocket and SignalR: Pros, Cons, and Use Cases
An In-Depth Comparison of WebSocket and SignalR: Pros, Cons, and Use CasesAn In-Depth Comparison of WebSocket and SignalR: Pros, Cons, and Use Cases
An In-Depth Comparison of WebSocket and SignalR: Pros, Cons, and Use Cases
 
Resilient and Adaptable Systems with Cloud Native APIs
Resilient and Adaptable Systems with Cloud Native APIsResilient and Adaptable Systems with Cloud Native APIs
Resilient and Adaptable Systems with Cloud Native APIs
 
Shedding Light on LINE Token Economy You Won't Find in Our White Paper
Shedding Light on LINE Token Economy You Won't Find in Our White PaperShedding Light on LINE Token Economy You Won't Find in Our White Paper
Shedding Light on LINE Token Economy You Won't Find in Our White Paper
 
Consul: Service Mesh for Microservices
Consul: Service Mesh for MicroservicesConsul: Service Mesh for Microservices
Consul: Service Mesh for Microservices
 
Testing in the 21st Century (ExpoQA)
Testing in the 21st Century (ExpoQA)Testing in the 21st Century (ExpoQA)
Testing in the 21st Century (ExpoQA)
 
Signal r
Signal rSignal r
Signal r
 
Client server chat application
Client server chat applicationClient server chat application
Client server chat application
 
Declarative Clients in Spring
Declarative Clients in SpringDeclarative Clients in Spring
Declarative Clients in Spring
 
WebSocket MicroService vs. REST Microservice
WebSocket MicroService vs. REST MicroserviceWebSocket MicroService vs. REST Microservice
WebSocket MicroService vs. REST Microservice
 
ClientServer Websocket.pptx
ClientServer Websocket.pptxClientServer Websocket.pptx
ClientServer Websocket.pptx
 
Techdays Helsinki - Creating the distributed apps of the future using dapr - ...
Techdays Helsinki - Creating the distributed apps of the future using dapr - ...Techdays Helsinki - Creating the distributed apps of the future using dapr - ...
Techdays Helsinki - Creating the distributed apps of the future using dapr - ...
 
KrakenD API Gateway
KrakenD API GatewayKrakenD API Gateway
KrakenD API Gateway
 
Working with PowerVC via its REST APIs
Working with PowerVC via its REST APIsWorking with PowerVC via its REST APIs
Working with PowerVC via its REST APIs
 
Encode x NEAR: Technical Overview of NEAR 1
Encode x NEAR: Technical Overview of NEAR 1Encode x NEAR: Technical Overview of NEAR 1
Encode x NEAR: Technical Overview of NEAR 1
 
Getting Started With WP REST API
Getting Started With WP REST APIGetting Started With WP REST API
Getting Started With WP REST API
 
58615764 net-and-j2 ee-web-services
58615764 net-and-j2 ee-web-services58615764 net-and-j2 ee-web-services
58615764 net-and-j2 ee-web-services
 
ITCamp 2011 - Florin Cardasim - Duplex Communications with WCF and Azure
ITCamp 2011 - Florin Cardasim - Duplex Communications with WCF and AzureITCamp 2011 - Florin Cardasim - Duplex Communications with WCF and Azure
ITCamp 2011 - Florin Cardasim - Duplex Communications with WCF and Azure
 
Smart networking with service meshes
Smart networking with service meshes  Smart networking with service meshes
Smart networking with service meshes
 
Svcc2009 Async Ws
Svcc2009 Async WsSvcc2009 Async Ws
Svcc2009 Async Ws
 

More from GR8Conf

More from GR8Conf (20)

DevOps Enabling Your Team
DevOps Enabling Your TeamDevOps Enabling Your Team
DevOps Enabling Your Team
 
Mum, I want to be a Groovy full-stack developer
Mum, I want to be a Groovy full-stack developerMum, I want to be a Groovy full-stack developer
Mum, I want to be a Groovy full-stack developer
 
Metaprogramming with Groovy
Metaprogramming with GroovyMetaprogramming with Groovy
Metaprogramming with Groovy
 
Scraping with Geb
Scraping with GebScraping with Geb
Scraping with Geb
 
How to create a conference android app with Groovy and Android
How to create a conference android app with Groovy and AndroidHow to create a conference android app with Groovy and Android
How to create a conference android app with Groovy and Android
 
Ratpack On the Docks
Ratpack On the DocksRatpack On the Docks
Ratpack On the Docks
 
Groovy Powered Clean Code
Groovy Powered Clean CodeGroovy Powered Clean Code
Groovy Powered Clean Code
 
Cut your Grails application to pieces - build feature plugins
Cut your Grails application to pieces - build feature pluginsCut your Grails application to pieces - build feature plugins
Cut your Grails application to pieces - build feature plugins
 
Performance tuning Grails applications
 Performance tuning Grails applications Performance tuning Grails applications
Performance tuning Grails applications
 
Ratpack and Grails 3
 Ratpack and Grails 3 Ratpack and Grails 3
Ratpack and Grails 3
 
Grails & DevOps: continuous integration and delivery in the cloud
Grails & DevOps: continuous integration and delivery in the cloudGrails & DevOps: continuous integration and delivery in the cloud
Grails & DevOps: continuous integration and delivery in the cloud
 
Functional testing your Grails app with GEB
Functional testing your Grails app with GEBFunctional testing your Grails app with GEB
Functional testing your Grails app with GEB
 
Deploying, Scaling, and Running Grails on AWS and VPC
Deploying, Scaling, and Running Grails on AWS and VPCDeploying, Scaling, and Running Grails on AWS and VPC
Deploying, Scaling, and Running Grails on AWS and VPC
 
The Grails introduction workshop
The Grails introduction workshopThe Grails introduction workshop
The Grails introduction workshop
 
Idiomatic spock
Idiomatic spockIdiomatic spock
Idiomatic spock
 
The Groovy Ecosystem Revisited
The Groovy Ecosystem RevisitedThe Groovy Ecosystem Revisited
The Groovy Ecosystem Revisited
 
Groovy 3 and the new Groovy Meta Object Protocol in examples
Groovy 3 and the new Groovy Meta Object Protocol in examplesGroovy 3 and the new Groovy Meta Object Protocol in examples
Groovy 3 and the new Groovy Meta Object Protocol in examples
 
Integration using Apache Camel and Groovy
Integration using Apache Camel and GroovyIntegration using Apache Camel and Groovy
Integration using Apache Camel and Groovy
 
CRaSH the shell for the Java Virtual Machine
CRaSH the shell for the Java Virtual MachineCRaSH the shell for the Java Virtual Machine
CRaSH the shell for the Java Virtual Machine
 
Grooscript gr8conf
Grooscript gr8confGrooscript gr8conf
Grooscript gr8conf
 

Recently uploaded

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
Enterprise Knowledge
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
Earley Information Science
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 

Recently uploaded (20)

How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Evaluating the top large language models.pdf
Evaluating the top large language models.pdfEvaluating the top large language models.pdf
Evaluating the top large language models.pdf
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 

Creating and testing REST contracts with Accurest Gradle

  • 1. Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 1 z 112 13.06.2016 13:47
  • 2. / oms@codearte.io@olga_maciaszek Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 2 z 112 13.06.2016 13:47
  • 3. 1. Introduction 2. Background 3. Solution Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 3 z 112 13.06.2016 13:47
  • 4. Accurest - Consumer Driven ContractsAccurest - Consumer Driven Contracts Verifier for REST and MessagingVerifier for REST and Messaging Easy to write scripts Works out of the box with Gradle and Maven Automatically generated WireMock and Messaging stubs Automatically generated Spock/ JUnit tests Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 4 z 112 13.06.2016 13:47
  • 5. Tech StackTech Stack Gradle, Maven Java, Groovy REST: Standalone App, MockMvc, JAX-RS Messaging: Spring Integration, Spring Cloud Stream, Apache Camel Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 5 z 112 13.06.2016 13:47
  • 6. MonolithMonolith Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 6 z 112 13.06.2016 13:47
  • 7. Lengthy and Costly Development Process Long Testing Times Long Deployment Times Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 7 z 112 13.06.2016 13:47
  • 8. MicroservicesMicroservices Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 8 z 112 13.06.2016 13:47
  • 9. Many smaller services Each team responsible for its service REST communication Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 9 z 112 13.06.2016 13:47
  • 10. New Issues and ChallengesNew Issues and Challenges Creating and modifying REST contracts Testing a Microservice-based system Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 10 z 112 13.06.2016 13:47
  • 11. New Issues and ChallengesNew Issues and Challenges Creating and modifying REST contracts Testing a Microservice-based system Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 11 z 112 13.06.2016 13:47
  • 12. One server + limited clients vs. Multiple client/servers communicating with each other Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 12 z 112 13.06.2016 13:47
  • 13. Defining and modifying REST contracts much more often Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 13 z 112 13.06.2016 13:47
  • 14. Quick information when the REST contract is modified Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 14 z 112 13.06.2016 13:47
  • 15. Various clients requesting different changes at the same time Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 15 z 112 13.06.2016 13:47
  • 16. RequirementsRequirements Consumer Driven Contracts All consumers need to be notified when the Contract has changed Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 16 z 112 13.06.2016 13:47
  • 17. New Issues and ChallengesNew Issues and Challenges Creating and modifying REST contracts Testing a Microservice-based system Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 17 z 112 13.06.2016 13:47
  • 18. Monolith E2E TestsMonolith E2E Tests Comprehensive Verified borders Considerably improved safety Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 18 z 112 13.06.2016 13:47
  • 19. 1 to rule them all1 to rule them all Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 19 z 112 13.06.2016 13:47
  • 20. Against the very idea of microservices!Against the very idea of microservices! Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 20 z 112 13.06.2016 13:47
  • 21. 1 pipeline per service, all the1 pipeline per service, all the collaborators addedcollaborators added Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 21 z 112 13.06.2016 13:47
  • 22. Too costly!Too costly! Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 22 z 112 13.06.2016 13:47
  • 23. Stubbed collaboratorsStubbed collaborators Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 23 z 112 13.06.2016 13:47
  • 24. Stubs get corrodedStubs get corroded Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 24 z 112 13.06.2016 13:47
  • 25. RequirementsRequirements Stubs required Validating stubs against servers required Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 25 z 112 13.06.2016 13:47
  • 26. RequirementsRequirements Consumer Driven Contracts All consumers need to be notified when the Contract has changed Stubs required Validating stubs against servers required Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 26 z 112 13.06.2016 13:47
  • 27. AccurestAccurest Scripts that define the REST contracts are submitted as PRs by the client teams Scripts are used to generate both WireMock stubs and server tests New server version along the new stubs only published when server tests have passed Client services download server stubs and use them for tests Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 27 z 112 13.06.2016 13:47
  • 28. Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 28 z 112 13.06.2016 13:47
  • 29. Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 29 z 112 13.06.2016 13:47
  • 30. io.codearte.accurest.dsl.Accurest.make request { method 'PUT' url '/fraudcheck' body( clientId: "12345678902", loanAmount: 99999 ) headers { header('Content-Type', 'application/vnd.fraud.v1+json') } } response { status 200 body( fraudCheckStatus: "FRAUD", rejectionReason: "Amount too high" ) headers { header('Content-Type': 'application/vnd.fraud.v1+json') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 30 z 112 13.06.2016 13:47
  • 31. io.codearte.accurest.dsl.Accurest.make request { method 'PUT' url '/fraudcheck' body( clientId: "12345678902", loanAmount: 99999 ) headers { header('Content-Type', 'application/vnd.fraud.v1+json') } } response { status 200 body( fraudCheckStatus: "FRAUD", rejectionReason: "Amount too high" ) headers { header('Content-Type': 'application/vnd.fraud.v1+json') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 31 z 112 13.06.2016 13:47
  • 32. io.codearte.accurest.dsl.Accurest.make request { method 'PUT' url '/fraudcheck' body( clientId: "12345678902", loanAmount: 99999 ) headers { header('Content-Type', 'application/vnd.fraud.v1+json') } } response { status 200 body( fraudCheckStatus: "FRAUD", rejectionReason: "Amount too high" ) headers { header('Content-Type': 'application/vnd.fraud.v1+json') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 32 z 112 13.06.2016 13:47
  • 33. io.codearte.accurest.dsl.Accurest.make request { method 'PUT' url '/fraudcheck' body( clientId: "12345678902", loanAmount: 99999 ) headers { header('Content-Type', 'application/vnd.fraud.v1+json') } } response { status 200 body( fraudCheckStatus: "FRAUD", rejectionReason: "Amount too high" ) headers { header('Content-Type': 'application/vnd.fraud.v1+json') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 33 z 112 13.06.2016 13:47
  • 34. io.codearte.accurest.dsl.Accurest.make request { method 'PUT' url '/fraudcheck' body( clientId: "12345678902", loanAmount: 99999 ) headers { header('Content-Type', 'application/vnd.fraud.v1+json') } } response { status 200 body( fraudCheckStatus: "FRAUD", rejectionReason: "Amount too high" ) headers { header('Content-Type': 'application/vnd.fraud.v1+json') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 34 z 112 13.06.2016 13:47
  • 35. io.codearte.accurest.dsl.Accurest.make request { method 'PUT' url '/fraudcheck' body( clientId: "12345678902", loanAmount: 99999 ) headers { header('Content-Type', 'application/vnd.fraud.v1+json') } } response { status 200 body( fraudCheckStatus: "FRAUD", rejectionReason: "Amount too high" ) headers { header('Content-Type': 'application/vnd.fraud.v1+json') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 35 z 112 13.06.2016 13:47
  • 36. io.codearte.accurest.dsl.Accurest.make request { method 'PUT' url '/fraudcheck' body( clientId: "12345678902", loanAmount: 99999 ) headers { header('Content-Type', 'application/vnd.fraud.v1+json') } } response { status 200 body( fraudCheckStatus: "FRAUD", rejectionReason: "Amount too high" ) headers { header('Content-Type': 'application/vnd.fraud.v1+json') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 36 z 112 13.06.2016 13:47
  • 37. io.codearte.accurest.dsl.Accurest.make request { method 'PUT' url '/fraudcheck' body( clientId: "12345678902", loanAmount: 99999 ) headers { header('Content-Type', 'application/vnd.fraud.v1+json') } } response { status 200 body( fraudCheckStatus: "FRAUD", rejectionReason: "Amount too high" ) headers { header('Content-Type': 'application/vnd.fraud.v1+json') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 37 z 112 13.06.2016 13:47
  • 38. io.codearte.accurest.dsl.Accurest.make request { method 'PUT' url '/fraudcheck' body( clientId: "12345678902", loanAmount: 99999 ) headers { header('Content-Type', 'application/vnd.fraud.v1+json') } } response { status 200 body( fraudCheckStatus: "FRAUD", rejectionReason: "Amount too high" ) headers { header('Content-Type': 'application/vnd.fraud.v1+json') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 38 z 112 13.06.2016 13:47
  • 39. io.codearte.accurest.dsl.Accurest.make request { method 'PUT' url '/fraudcheck' body( clientId: "12345678902", loanAmount: 99999 ) headers { header('Content-Type', 'application/vnd.fraud.v1+json') } } response { status 200 body( fraudCheckStatus: "FRAUD", rejectionReason: "Amount too high" ) headers { header('Content-Type': 'application/vnd.fraud.v1+json') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 39 z 112 13.06.2016 13:47
  • 40. Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 40 z 112 13.06.2016 13:47
  • 41. Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 41 z 112 13.06.2016 13:47
  • 42. WireMockWireMock Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 42 z 112 13.06.2016 13:47
  • 43. { "request" : { "url" : "/fraudcheck", "method" : "PUT", "bodyPatterns" : [ { "matchesJsonPath" : "$[?(@.loanAmount == 99999)]" }, { "matchesJsonPath" : "$[?(@.clientId == '12345678902')]" } ], "headers" : { "Content-Type" : { "equalTo" : "application/vnd.fraud.v1+json" } } }, "response" : { "status" : 200, "body" : "{"fraudCheckStatus":"FRAUD", "rejectionReason":"Amount too high"}", "headers" : { "Content-Type" : "application/vnd.fraud.v1+json" } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 43 z 112 13.06.2016 13:47
  • 44. { "request" : { "url" : "/fraudcheck", "method" : "PUT", "bodyPatterns" : [ { "matchesJsonPath" : "$[?(@.loanAmount == 99999)]" }, { "matchesJsonPath" : "$[?(@.clientId == '12345678902')]" } ], "headers" : { "Content-Type" : { "equalTo" : "application/vnd.fraud.v1+json" } } } , "response" : { "status" : 200, "body" : "{"fraudCheckStatus":"FRAUD", "rejectionReason":"Amount too high"}", "headers" : { "Content-Type" : "application/vnd.fraud.v1+json" } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 44 z 112 13.06.2016 13:47
  • 45. io.codearte.accurest.dsl.Accurest.make request { method 'PUT' url '/fraudcheck' body( clientId: "12345678902", loanAmount: 99999 ) headers { header('Content-Type', 'application/vnd.fraud.v1+json') } } response { status 200 body( fraudCheckStatus: "FRAUD", rejectionReason: "Amount too high" ) headers { header('Content-Type': 'application/vnd.fraud.v1+json') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 45 z 112 13.06.2016 13:47
  • 46. { "request" : { "url" : "/fraudcheck", "method" : "PUT", "bodyPatterns" : [ { "matchesJsonPath" : "$[?(@.loanAmount == 99999)]" }, { "matchesJsonPath" : "$[?(@.clientId == '12345678902')]" } ], "headers" : { "Content-Type" : { "equalTo" : "application/vnd.fraud.v1+json" } } }, "response" : { "status" : 200, "body" : "{"fraudCheckStatus":"FRAUD", "rejectionReason":"Amount too high"}", "headers" : { "Content-Type" : "application/vnd.fraud.v1+json" } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 46 z 112 13.06.2016 13:47
  • 47. io.codearte.accurest.dsl.Accurest.make request { method 'PUT' url '/fraudcheck' body( clientId: "12345678902", loanAmount: 99999 ) headers { header('Content-Type', 'application/vnd.fraud.v1+json') } } response { status 200 body( fraudCheckStatus: "FRAUD", rejectionReason: "Amount too high" ) headers { header('Content-Type': 'application/vnd.fraud.v1+json') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 47 z 112 13.06.2016 13:47
  • 48. { "request" : { "url" : "/fraudcheck", "method" : "PUT", "bodyPatterns" : [ { "matchesJsonPath" : "$[?(@.loanAmount == 99999)]" }, { "matchesJsonPath" : "$[?(@.clientId == '12345678902')]" } ], "headers" : { "Content-Type" : { "equalTo" : "application/vnd.fraud.v1+json" } } }, "response" : { "status" : 200, "body" : "{"fraudCheckStatus":"FRAUD", "rejectionReason":"Amount too high"}", "headers" : { "Content-Type" : "application/vnd.fraud.v1+json" } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 48 z 112 13.06.2016 13:47
  • 49. io.codearte.accurest.dsl.Accurest.make request { method 'PUT' url '/fraudcheck' body( clientId: "12345678902", loanAmount: 99999 ) headers { header('Content-Type', 'application/vnd.fraud.v1+json') } } response { status 200 body( fraudCheckStatus: "FRAUD", rejectionReason: "Amount too high" ) headers { header('Content-Type': 'application/vnd.fraud.v1+json') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 49 z 112 13.06.2016 13:47
  • 50. { "request" : { "url" : "/fraudcheck", "method" : "PUT", "bodyPatterns" : [ { "matchesJsonPath" : "$[?(@.loanAmount == 99999)]" }, { "matchesJsonPath" : "$[?(@.clientId == '12345678902')]" } ], "headers" : { "Content-Type" : { "equalTo" : "application/vnd.fraud.v1+json" } } }, "response" : { "status" : 200, "body" : "{"fraudCheckStatus":"FRAUD", "rejectionReason":"Amount too high"}", "headers" : { "Content-Type" : "application/vnd.fraud.v1+json" } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 50 z 112 13.06.2016 13:47
  • 51. io.codearte.accurest.dsl.Accurest.make request { method 'PUT' url '/fraudcheck' body( clientId: "12345678902", loanAmount: 99999 ) headers { header('Content-Type', 'application/vnd.fraud.v1+json') } } response { status 200 body( fraudCheckStatus: "FRAUD", rejectionReason: "Amount too high" ) headers { header('Content-Type': 'application/vnd.fraud.v1+json') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 51 z 112 13.06.2016 13:47
  • 52. { "request" : { "url" : "/fraudcheck", "method" : "PUT", "bodyPatterns" : [ { "matchesJsonPath" : "$[?(@.loanAmount == 99999)]" }, { "matchesJsonPath" : "$[?(@.clientId == '12345678902')]" } ], "headers" : { "Content-Type" : { "equalTo" : "application/vnd.fraud.v1+json" } } }, "response" : { "status" : 200, "body" : "{"fraudCheckStatus":"FRAUD", "rejectionReason":"Amount too high"}", "headers" : { "Content-Type" : "application/vnd.fraud.v1+json" } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 52 z 112 13.06.2016 13:47
  • 53. { "request" : { "url" : "/fraudcheck", "method" : "PUT", "bodyPatterns" : [ { "matchesJsonPath" : "$[?(@.loanAmount == 99999)]" }, { "matchesJsonPath" : "$[?(@.clientId == '12345678902')]" } ], "headers" : { "Content-Type" : { "equalTo" : "application/vnd.fraud.v1+json" } } }, "response" : { "status" : 200, "body" : "{"fraudCheckStatus":"FRAUD", "rejectionReason":"Amount too high"}", "headers" : { "Content-Type" : "application/vnd.fraud.v1+json" } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 53 z 112 13.06.2016 13:47
  • 54. io.codearte.accurest.dsl.Accurest.make request { method 'PUT' url '/fraudcheck' body( clientId: "12345678902", loanAmount: 99999 ) headers { header('Content-Type', 'application/vnd.fraud.v1+json') } } response { status 200 body( fraudCheckStatus: "FRAUD", rejectionReason: "Amount too high" ) headers { header('Content-Type': 'application/vnd.fraud.v1+json') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 54 z 112 13.06.2016 13:47
  • 55. { "request" : { "url" : "/fraudcheck", "method" : "PUT", "bodyPatterns" : [ { "matchesJsonPath" : "$[?(@.loanAmount == 99999)]" }, { "matchesJsonPath" : "$[?(@.clientId == '12345678902')]" } ], "headers" : { "Content-Type" : { "equalTo" : "application/vnd.fraud.v1+json" } } }, "response" : { "status" : 200, "body" : "{"fraudCheckStatus":"FRAUD", "rejectionReason":"Amount too high"}", "headers" : { "Content-Type" : "application/vnd.fraud.v1+json" } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 55 z 112 13.06.2016 13:47
  • 56. io.codearte.accurest.dsl.Accurest.make request { method 'PUT' url '/fraudcheck' body( clientId: "12345678902", loanAmount: 99999 ) headers { header('Content-Type', 'application/vnd.fraud.v1+json') } } response { status 200 body( fraudCheckStatus: "FRAUD", rejectionReason: "Amount too high" ) headers { header('Content-Type': 'application/vnd.fraud.v1+json') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 56 z 112 13.06.2016 13:47
  • 57. { "request" : { "url" : "/fraudcheck", "method" : "PUT", "bodyPatterns" : [ { "matchesJsonPath" : "$[?(@.loanAmount == 99999)]" }, { "matchesJsonPath" : "$[?(@.clientId == '12345678902')]" } ], "headers" : { "Content-Type" : { "equalTo" : "application/vnd.fraud.v1+json" } } }, "response" : { "status" : 200, "body" : "{"fraudCheckStatus":"FRAUD", "rejectionReason":"Amount too high"}", "headers" : { "Content-Type" : "application/vnd.fraud.v1+json" } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 57 z 112 13.06.2016 13:47
  • 58. io.codearte.accurest.dsl.Accurest.make request { method 'PUT' url '/fraudcheck' body( clientId: "12345678902", loanAmount: 99999 ) headers { header('Content-Type', 'application/vnd.fraud.v1+json') } } response { status 200 body( fraudCheckStatus: "FRAUD", rejectionReason: "Amount too high" ) headers { header('Content-Type': 'application/vnd.fraud.v1+json') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 58 z 112 13.06.2016 13:47
  • 59. { "request" : { "url" : "/fraudcheck", "method" : "PUT", "bodyPatterns" : [ { "matchesJsonPath" : "$[?(@.loanAmount == 99999)]" }, { "matchesJsonPath" : "$[?(@.clientId == '12345678902')]" } ], "headers" : { "Content-Type" : { "equalTo" : "application/vnd.fraud.v1+json" } } }, "response" : { "status" : 200, "body" : "{"fraudCheckStatus":"FRAUD", "rejectionReason":"Amount too high"}", "headers" : { "Content-Type" : "application/vnd.fraud.v1+json" } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 59 z 112 13.06.2016 13:47
  • 60. Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 60 z 112 13.06.2016 13:47
  • 61. Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 61 z 112 13.06.2016 13:47
  • 62. def validate_shouldMarkClientAsFraud() { given: def request = given() .header('Content-Type', 'application/vnd.fraud.v1+json') .body('{"clientId":"12345678902","loanAmount":99999}') when: def response = given().spec(request).put("/fraudcheck") then: response.statusCode == 200 response.header('Content-Type') == 'application/vnd.fraud.v1+json' and: DocumentContext parsedJson = JsonPath.parse(response.body.asString()) assertTassertThatJson(parsedJson).field("rejectionReason") .isEqualTo("Amount too high") assertThatJson(parsedJson).field("fraudCheckStatus").isEqualTo("FRAUD") } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 62 z 112 13.06.2016 13:47
  • 63. com.jayway.RestAssured com.toomuchcoding.jsonassert Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 63 z 112 13.06.2016 13:47
  • 64. io.codearte.accurest.dsl.Accurest.make request { method 'PUT' url '/fraudcheck' body( clientId: "12345678902", loanAmount: 99999 ) headers { header('Content-Type', 'application/vnd.fraud.v1+json') } } response { status 200 body( fraudCheckStatus: "FRAUD", rejectionReason: "Amount too high" ) headers { header('Content-Type': 'application/vnd.fraud.v1+json') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 64 z 112 13.06.2016 13:47
  • 65. def validate_shouldMarkClientAsFraud() { given: def request = given() .header('Content-Type', 'application/vnd.fraud.v1+json') .body('{"clientId":"12345678902","loanAmount":99999}') when: def response = given().spec(request).put("/fraudcheck") then: response.statusCode == 200 response.header('Content-Type') == 'application/vnd.fraud.v1+json' and: DocumentContext parsedJson = JsonPath.parse(response.body.asString()) assertTassertThatJson(parsedJson).field("rejectionReason") .isEqualTo("Amount too high") assertThatJson(parsedJson).field("fraudCheckStatus").isEqualTo("FRAUD") } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 65 z 112 13.06.2016 13:47
  • 66. io.codearte.accurest.dsl.Accurest.make request { method 'PUT' url '/fraudcheck' body( clientId: "12345678902", loanAmount: 99999 ) headers { header('Content-Type', 'application/vnd.fraud.v1+json') } } response { status 200 body( fraudCheckStatus: "FRAUD", rejectionReason: "Amount too high" ) headers { header('Content-Type': 'application/vnd.fraud.v1+json') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 66 z 112 13.06.2016 13:47
  • 67. def validate_shouldMarkClientAsFraud() { given: def request = given() .header('Content-Type', 'application/vnd.fraud.v1+json') .body('{"clientId":"12345678902","loanAmount":99999}') when: def response = given().spec(request).put("/fraudcheck") then: response.statusCode == 200 response.header('Content-Type') == 'application/vnd.fraud.v1+json' and: DocumentContext parsedJson = JsonPath.parse(response.body.asString()) assertThatJson(parsedJson).field("rejectionReason") .isEqualTo("Amount too high") assertThatJson(parsedJson).field("fraudCheckStatus").isEqualTo("FRAUD") } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 67 z 112 13.06.2016 13:47
  • 68. io.codearte.accurest.dsl.Accurest.make request { method 'PUT' url '/fraudcheck' body( clientId: "12345678902", loanAmount: 99999 ) headers { header('Content-Type', 'application/vnd.fraud.v1+json') } } response { status 200 body( fraudCheckStatus: "FRAUD", rejectionReason: "Amount too high" ) headers { header('Content-Type': 'application/vnd.fraud.v1+json') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 68 z 112 13.06.2016 13:47
  • 69. def validate_shouldMarkClientAsFraud() { given: def request = given() .header('Content-Type', 'application/vnd.fraud.v1+json') .body('{"clientId":"12345678902","loanAmount":99999}') when: def response = given().spec(request).put("/fraudcheck") then: response.statusCode == 200 response.header('Content-Type') == 'application/vnd.fraud.v1+json' and: DocumentContext parsedJson = JsonPath.parse(response.body.asString()) assertThatJson(parsedJson).field("rejectionReason") .isEqualTo("Amount too high") assertThatJson(parsedJson).field("fraudCheckStatus").isEqualTo("FRAUD") } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 69 z 112 13.06.2016 13:47
  • 70. io.codearte.accurest.dsl.Accurest.make request { method 'PUT' url '/fraudcheck' body( clientId: "12345678902", loanAmount: 99999 ) headers { header('Content-Type', 'application/vnd.fraud.v1+json') } } response { status 200 body( fraudCheckStatus: "FRAUD", rejectionReason: "Amount too high" ) headers { header('Content-Type': 'application/vnd.fraud.v1+json') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 70 z 112 13.06.2016 13:47
  • 71. def validate_shouldMarkClientAsFraud() { given: def request = given() .header('Content-Type', 'application/vnd.fraud.v1+json') .body('{"clientId":"12345678902","loanAmount":99999}') when: def response = given().spec(request).put("/fraudcheck") then: response.statusCode == 200 response.header('Content-Type') == 'application/vnd.fraud.v1+json' and: DocumentContext parsedJson = JsonPath.parse(response.body.asString()) assertThatJson(parsedJson).field("rejectionReason") .isEqualTo("Amount too high") assertThatJson(parsedJson).field("fraudCheckStatus").isEqualTo("FRAUD") } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 71 z 112 13.06.2016 13:47
  • 72. io.codearte.accurest.dsl.Accurest.make request { method 'PUT' url '/fraudcheck' body( clientId: "12345678902", loanAmount: 99999 ) headers { header('Content-Type', 'application/vnd.fraud.v1+json') } } response { status 200 body( fraudCheckStatus: "FRAUD", rejectionReason: "Amount too high" ) headers { header('Content-Type': 'application/vnd.fraud.v1+json') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 72 z 112 13.06.2016 13:47
  • 73. def validate_shouldMarkClientAsFraud() { given: def request = given() .header('Content-Type', 'application/vnd.fraud.v1+json') .body('{"clientId":"12345678902","loanAmount":99999}') when: def response = given().spec(request).put("/fraudcheck") then: response.statusCode == 200 response.header('Content-Type') == 'application/vnd.fraud.v1+json' and: DocumentContext parsedJson = JsonPath.parse(response.body.asString()) assertThatJson(parsedJson).field("rejectionReason") .isEqualTo("Amount too high") assertThatJson(parsedJson).field("fraudCheckStatus").isEqualTo("FRAUD") } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 73 z 112 13.06.2016 13:47
  • 74. Base Test ClassBase Test Class class BaseMockMvcSpec extends Specification { def setup() { RestAssuredMockMvc.standaloneSetup(new PairIdController()) } } @ContextConfiguration(classes = [PaymentResourceStubContext, ClientResourceStubContext], loader = SpringApplicationContextLoader) @WebIntegrationTest class BaseAccurestSpec extends Specification { @Autowired ApplicationContext context } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 74 z 112 13.06.2016 13:47
  • 75. Regular Expression SupportRegular Expression Support Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 75 z 112 13.06.2016 13:47
  • 76. io.codearte.accurest.dsl.Accurest.make request { method 'PUT' url '/fraudcheck' body( clientId: value(stub(regex('[0-9]{11}')), test("12345678902")), loanAmount: 99999 ) headers { header('Content-Type', 'application/vnd.fraud.v1+json') } } response { status 200 body( fraudCheckStatus: "FRAUD", rejectionReason: "Amount too high" ) headers { header('Content-Type': 'application/vnd.fraud.v1+json') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 76 z 112 13.06.2016 13:47
  • 77. { "request" : { "url" : "/fraudcheck", "method" : "PUT", "bodyPatterns" : [ { "matchesJsonPath" : "$[?(@.loanAmount == 99999)]" }, { "matchesJsonPath" : "$[?(@.clientId =~ /[0-9]{11}/)]" } ], "headers" : { "Content-Type" : { "equalTo" : "application/vnd.fraud.v1+json" } } }, "response" : { "status" : 200, "body" : "{"fraudCheckStatus":"FRAUD", "rejectionReason":"Amount too high"}", "headers" : { "Content-Type" : "application/vnd.fraud.v1+json" } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 77 z 112 13.06.2016 13:47
  • 78. def validate_shouldMarkClientAsFraud() { given: def request = given() .header('Content-Type', 'application/vnd.fraud.v1+json') .body('{"clientId":"12345678902" ,"loanAmount":99999}') when: def response = given().spec(request).put("/fraudcheck") then: response.statusCode == 200 response.header('Content-Type') == 'application/vnd.fraud.v1+json' and: DocumentContext parsedJson = JsonPath.parse(response.body.asString()) assertThatJson(parsedJson).field("rejectionReason") .isEqualTo("Amount too high") assertThatJson(parsedJson).field("fraudCheckStatus").isEqualTo("FRAUD") } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 78 z 112 13.06.2016 13:47
  • 79. Executing Custom Methods on theExecuting Custom Methods on the ServerServer Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 79 z 112 13.06.2016 13:47
  • 80. io.codearte.accurest.dsl.Accurest.make request { method 'PUT' url '/fraudcheck' body( clientId: "12345678902", loanAmount: 99999 ) headers { header('Content-Type', 'application/vnd.fraud.v1+json') } } response { status 200 body(fraudCheckStatus: "FRAUD", rejectionReason: value(stub("Amount too high"), test(execute('isCorrectRejectionReason($it)')))) headers { header('Content-Type': 'application/vnd.fraud.v1+json') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 80 z 112 13.06.2016 13:47
  • 81. abstract class BaseMockMvcSpec extends Specification { def setup() { RestAssuredMockMvc.standaloneSetup(new FraudDetectionController()) } void isCorrectRejectionReason(String rejectionReason) { assert rejectionReason == 'Amount too high' } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 81 z 112 13.06.2016 13:47
  • 82. def validate_shouldMarkClientAsFraud() { given: def request = given() .header('Content-Type', 'application/vnd.fraud.v1+json') .body('{"clientId":"12345678902","loanAmount":99999}') when: def response = given().spec(request).put("/fraudcheck") then: response.statusCode == 200 response.header('Content-Type') == 'application/vnd.fraud.v1+json' and: DocumentContext parsedJson = JsonPath.parse(response.body.asString()) assertThatJson(parsedJson).field("fraudCheckStatus").isEqualTo("FRAUD") isCorrectRejectionReason(parsedJson.read('$.rejectionReason')) } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 82 z 112 13.06.2016 13:47
  • 83. DSL - Other Available FunctionalitiesDSL - Other Available Functionalities Query Parameters Optional Fields Nested Elements Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 83 z 112 13.06.2016 13:47
  • 84. Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 84 z 112 13.06.2016 13:47
  • 85. Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 85 z 112 13.06.2016 13:47
  • 86. Stubs published as jars to theStubs published as jars to the repositoryrepository Jar, archive Maven Publish Plugin Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 86 z 112 13.06.2016 13:47
  • 87. Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 87 z 112 13.06.2016 13:47
  • 88. StubRunnerStubRunner Automated stubs download from the repository Automated launching of WireMock server instances and mounting the stubs Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 88 z 112 13.06.2016 13:47
  • 89. StubRunner DependenciesStubRunner Dependencies dependencies { testCompile 'io.codearte.accurest:stub-runner:1.1.0-M7' testCompile 'io.codearte.accurest:stub-runner-junit:1.1.0-M7' testCompile 'io.codearte.accurest:stub-runner-spring:1.1.0-M7' testCompile 'io.codearte.accurest:stub-runner-spring-cloud:1.1.0-M7' } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 89 z 112 13.06.2016 13:47
  • 90. Accurest JUnit RuleAccurest JUnit Rule @ClassRule @Shared AccurestRule accurestRule = new AccurestRule().repoRoot('http://www.myrepo.com') .minPort(11000).maxPort(12000) [ || .withPort(8090)] .downloadStub('com.toomuchcoding:fraudDetectionService') Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 90 z 112 13.06.2016 13:47
  • 91. Out of the box support for Spring andOut of the box support for Spring and SpringCloudSpringCloud StubRunnerConfiguration @Autowired StubFinder StubRunnerDiscoveryClient Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 91 z 112 13.06.2016 13:47
  • 92. MessagingMessaging Automated testing of messages created by the producer Producer's messages automatically provided for consumer tests by StubRunner Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 92 z 112 13.06.2016 13:47
  • 93. Producer SideProducer Side Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 93 z 112 13.06.2016 13:47
  • 94. io.codearte.accurest.dsl.Accurest.make { description 'Some Description' label 'some_label' input { messageFrom('input') messageBody([ bookName: 'foo' ]) messageHeaders { header('sample', 'header') } } outputMessage { sentTo('output') body([ bookName: 'foo' ]) headers { header('BOOK-NAME', 'foo') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 94 z 112 13.06.2016 13:47
  • 95. def validate_shouldMakeMessageTest() throws Exception { given: def inputMessage = accurestMessaging.create('''{"bookName":"foo"}''' ,[ 'sample': 'header' ]) when: accurestMessaging.send(inputMessage, 'input') then: def response = accurestMessaging.receiveMessage('output') assert response != null response.getHeader('BOOK-NAME') == 'foo' and: DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper .writeValueAsString(response.payload)) assertThatJson(parsedJson).field("bookName").isEqualTo("foo") } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 95 z 112 13.06.2016 13:47
  • 96. io.codearte.accurest.dsl.Accurest.make { description 'Some Description' label 'some_label' input { messageFrom('input') messageBody([ bookName: 'foo' ]) messageHeaders { header('sample', 'header') } } outputMessage { sentTo('output') body([ bookName: 'foo ]) headers { header('BOOK-NAME', 'foo') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 96 z 112 13.06.2016 13:47
  • 97. def validate_shouldMakeMessageTest() throws Exception { given: def inputMessage = accurestMessaging.create('''{"bookName":"foo"}''' ,[ 'sample': 'header' ]) when: accurestMessaging.send(inputMessage, 'input') then: def response = accurestMessaging.receiveMessage('output') assert response != null response.getHeader('BOOK-NAME') == 'foo' and: DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper .writeValueAsString(response.payload)) assertThatJson(parsedJson).field("bookName").isEqualTo("foo") } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 97 z 112 13.06.2016 13:47
  • 98. io.codearte.accurest.dsl.Accurest.make { description 'Some Description' label 'some_label' input { messageFrom('input') messageBody([ bookName: 'foo' ]) messageHeaders { header('sample', 'header') } } outputMessage { sentTo('output') body([ bookName: 'foo ]) headers { header('BOOK-NAME', 'foo') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 98 z 112 13.06.2016 13:47
  • 99. def validate_shouldMakeMessageTest() throws Exception { given: def inputMessage = accurestMessaging.create('''{"bookName":"foo"}''' ,[ 'sample': 'header' ]) when: accurestMessaging.send(inputMessage, 'input') then: def response = accurestMessaging.receiveMessage('output') assert response != null response.getHeader('BOOK-NAME') == 'foo' and: DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper .writeValueAsString(response.payload)) assertThatJson(parsedJson).field("bookName").isEqualTo("foo") } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 99 z 112 13.06.2016 13:47
  • 100. io.codearte.accurest.dsl.Accurest.make { description 'Some Description' label 'some_label' input { messageFrom('input') messageBody([ bookName: 'foo' ]) messageHeaders { header('sample', 'header') } } outputMessage { sentTo('output') body([ bookName: 'foo ]) headers { header('BOOK-NAME', 'foo') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 100 z 112 13.06.2016 13:47
  • 101. def validate_shouldMakeMessageTest() throws Exception { given: def inputMessage = accurestMessaging.create('''{"bookName":"foo"}''' ,[ 'sample': 'header' ]) when: accurestMessaging.send(inputMessage, 'input') then: def response = accurestMessaging.receiveMessage('output') assert response != null response.getHeader('BOOK-NAME') == 'foo' and: DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper .writeValueAsString(response.payload)) assertThatJson(parsedJson).field("bookName").isEqualTo("foo") } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 101 z 112 13.06.2016 13:47
  • 102. io.codearte.accurest.dsl.Accurest.make { description 'Some Description' label 'some_label' input { messageFrom('input') messageBody([ bookName: 'foo' ]) messageHeaders { header('sample', 'header') } } outputMessage { sentTo('output') body([ bookName: 'foo ]) headers { header('BOOK-NAME', 'foo') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 102 z 112 13.06.2016 13:47
  • 103. def validate_shouldMakeMessageTest() throws Exception { given: def inputMessage = accurestMessaging.create('''{"bookName":"foo"}'''> ,[ 'sample': 'header' ]) when: accurestMessaging.send(inputMessage,'input') then: def response = accurestMessaging.receiveMessage('output') assert response != null response.getHeader('BOOK-NAME') == 'foo' and: DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper .writeValueAsString(response.payload)) assertThatJson(parsedJson).field("bookName").isEqualTo("foo") } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 103 z 112 13.06.2016 13:47
  • 104. io.codearte.accurest.dsl.Accurest.make { description 'Some Description' label 'some_label' input { messageFrom('input') messageBody([ bookName: 'foo' ]) messageHeaders { header('sample', 'header') } } outputMessage { sentTo('output') body([ bookName: 'foo ]) headers { header('BOOK-NAME', 'foo') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 104 z 112 13.06.2016 13:47
  • 105. def validate_shouldMakeMessageTest() throws Exception { given: def inputMessage = accurestMessaging.create('''{"bookName":"foo"}'''> ,[ 'sample': 'header' ]) when: accurestMessaging.send(inputMessage,'input') then: def response = accurestMessaging.receiveMessage('output') assert response != null response.getHeader('BOOK-NAME') == 'foo' and: DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper .writeValueAsString(response.payload)) assertThatJson(parsedJson).field("bookName").isEqualTo("foo") } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 105 z 112 13.06.2016 13:47
  • 106. io.codearte.accurest.dsl.Accurest.make { description 'Some Description' label 'some_label' input { messageFrom('input') messageBody([ bookName: 'foo' ]) messageHeaders { header('sample', 'header') } } outputMessage { sentTo('output') body([ bookName: 'foo ]) headers { header('BOOK-NAME', 'foo') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 106 z 112 13.06.2016 13:47
  • 107. def validate_shouldMakeMessageTest() throws Exception { given: def inputMessage = accurestMessaging.create('''{"bookName":"foo"}'''> ,[ 'sample': 'header' ]) when: accurestMessaging.send(inputMessage,'input') then: def response = accurestMessaging.receiveMessage('output') assert response != null response.getHeader('BOOK-NAME') == 'foo' and: DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper .writeValueAsString(response.payload)) assertThatJson(parsedJson).field("bookName").isEqualTo("foo") } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 107 z 112 13.06.2016 13:47
  • 108. io.codearte.accurest.dsl.Accurest.make { description 'Some description' label 'some_label' input { triggeredBy('bookReturnedTriggered()') } outputMessage { sentTo('output') body('''{ "bookName" : "foo" }''') headers { header('BOOK-NAME', 'foo') } } } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 108 z 112 13.06.2016 13:47
  • 109. def validate_shouldMakeMessageTest() throws Exception { when: bookReturnedTriggered() then: def response = accurestMessaging.receiveMessage('output') assert response != null response.getHeader('BOOK-NAME') == 'foo' and: DocumentContext parsedJson = JsonPath.parse(accurestObjectMapper .writeValueAsString(response.payload)) assertThatJson(parsedJson).field("bookName").isEqualTo("foo") } Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 109 z 112 13.06.2016 13:47
  • 110. Consumer SideConsumer Side testCompile "io. codearte.accurest:accurest-messaging-camel:${accurestVersion}" testCompile "io.codearte.accurest:accurest-messaging-integration:${accurestVersion}" testCompile "io.codearte.accurest:accurest-messaging-stream:${accurestVersion}" Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 110 z 112 13.06.2016 13:47
  • 111. Possible IssuesPossible Issues Complex Systems Test Base Class Gradle Setup Young solution Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 111 z 112 13.06.2016 13:47
  • 112. / / Thank youThank you https://github.com/Codearte/accurest branch: 08_publish_stubs https://github.com/OlgaMaciaszek/cdc_examples branch: 02_with_accurest_rule https://github.com/OlgaMaciaszek /LoanApplicationService Olga Maciaszek-Sharma @olga_maciaszek oms@codearte.io Creating and Testing REST and Messaging Contracts with Accurest http://localhost:8000/?print-pdf#/ 112 z 112 13.06.2016 13:47