Skip to content

Commit ed45066

Browse files
committed
updated pact-feign example to Spring Boot 2 and JUnit 5
1 parent fb148fc commit ed45066

File tree

7 files changed

+234
-76
lines changed

7 files changed

+234
-76
lines changed
Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
apply plugin: 'org.springframework.boot'
2-
31
buildscript {
42
repositories {
53
mavenLocal()
@@ -10,18 +8,43 @@ buildscript {
108
}
119
}
1210

11+
plugins {
12+
id "au.com.dius.pact" version "3.5.20"
13+
}
14+
15+
apply plugin: 'java'
16+
apply plugin: 'org.springframework.boot'
17+
apply plugin: 'io.spring.dependency-management'
18+
19+
version '1.0.0.SNAPSHOT'
1320

1421
repositories {
1522
mavenLocal()
1623
jcenter()
1724
}
1825

26+
dependencyManagement {
27+
imports {
28+
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springcloud_version}"
29+
}
30+
}
31+
1932
dependencies {
20-
compile("org.springframework.boot:spring-boot-starter-data-jpa:${springboot_version}")
21-
compile("org.springframework.boot:spring-boot-starter-web:${springboot_version}")
22-
compile("org.springframework.cloud:spring-cloud-starter-feign:1.4.1.RELEASE")
33+
compile('org.springframework.boot:spring-boot-starter-data-jpa')
34+
compile('org.springframework.boot:spring-boot-starter-web')
35+
compile('org.springframework.cloud:spring-cloud-starter-openfeign')
36+
compile('org.springframework.cloud:spring-cloud-starter-netflix-ribbon')
2337
compile('com.h2database:h2:1.4.196')
2438
testCompile('org.codehaus.groovy:groovy-all:2.4.6')
25-
testCompile("au.com.dius:pact-jvm-consumer-junit_2.11:3.5.2")
26-
testCompile("org.springframework.boot:spring-boot-starter-test:${springboot_version}")
39+
testCompile("au.com.dius:pact-jvm-consumer-junit5_2.12:${pact_version}")
40+
testCompile('org.springframework.boot:spring-boot-starter-test')
2741
}
42+
43+
pact {
44+
publish {
45+
pactDirectory = 'target/pacts'
46+
pactBrokerUrl = 'URL'
47+
pactBrokerUsername = 'USERNAME'
48+
pactBrokerPassword = 'PASSWORD'
49+
}
50+
}
Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
springboot_version=1.5.9.RELEASE
2-
verifier_version=1.2.2.RELEASE
1+
springboot_version=2.0.4.RELEASE
2+
springcloud_version=Finchley.SR1
3+
pact_version=3.5.20

pact/pact-feign-consumer/src/main/java/io/reflectoring/ConsumerApplication.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22

33
import org.springframework.boot.SpringApplication;
44
import org.springframework.boot.autoconfigure.SpringBootApplication;
5-
import org.springframework.cloud.netflix.feign.EnableFeignClients;
5+
import org.springframework.cloud.netflix.ribbon.RibbonClient;
6+
import org.springframework.cloud.openfeign.EnableFeignClients;
67

78
@SpringBootApplication
89
@EnableFeignClients
10+
@RibbonClient(name = "userservice", configuration = RibbonConfiguration.class)
911
public class ConsumerApplication {
1012

1113
public static void main(String[] args) {
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package io.reflectoring;
2+
3+
import com.netflix.client.config.IClientConfig;
4+
import com.netflix.loadbalancer.IRule;
5+
import com.netflix.loadbalancer.RandomRule;
6+
import org.springframework.context.annotation.Bean;
7+
8+
public class RibbonConfiguration {
9+
10+
@Bean
11+
public IRule ribbonRule(IClientConfig config) {
12+
return new RandomRule();
13+
}
14+
15+
}

pact/pact-feign-consumer/src/main/java/io/reflectoring/UserClient.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package io.reflectoring;
22

3-
import org.springframework.cloud.netflix.feign.FeignClient;
3+
import org.springframework.cloud.openfeign.FeignClient;
44
import org.springframework.web.bind.annotation.PathVariable;
55
import org.springframework.web.bind.annotation.RequestBody;
66
import org.springframework.web.bind.annotation.RequestMapping;
Lines changed: 67 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,83 +1,85 @@
11
package io.reflectoring;
22

33
import au.com.dius.pact.consumer.Pact;
4-
import au.com.dius.pact.consumer.PactProviderRuleMk2;
5-
import au.com.dius.pact.consumer.PactVerification;
64
import au.com.dius.pact.consumer.dsl.PactDslJsonBody;
75
import au.com.dius.pact.consumer.dsl.PactDslWithProvider;
6+
import au.com.dius.pact.consumer.junit5.PactConsumerTestExt;
7+
import au.com.dius.pact.consumer.junit5.PactTestFor;
88
import au.com.dius.pact.model.RequestResponsePact;
9-
import org.junit.Rule;
10-
import org.junit.Test;
11-
import org.junit.runner.RunWith;
9+
import org.junit.jupiter.api.Test;
10+
import org.junit.jupiter.api.extension.ExtendWith;
1211
import org.springframework.beans.factory.annotation.Autowired;
1312
import org.springframework.boot.test.context.SpringBootTest;
14-
import org.springframework.test.context.junit4.SpringRunner;
15-
import static org.assertj.core.api.Assertions.assertThat;
13+
import org.springframework.test.context.junit.jupiter.SpringExtension;
14+
import static org.assertj.core.api.Assertions.*;
1615

17-
@RunWith(SpringRunner.class)
18-
@SpringBootTest(properties = {
19-
// overriding provider address
20-
"userservice.ribbon.listOfServers: localhost:8888"
16+
@ExtendWith(PactConsumerTestExt.class)
17+
@ExtendWith(SpringExtension.class)
18+
@PactTestFor(providerName = "userservice", port = "8888")
19+
@SpringBootTest({
20+
// overriding provider address
21+
"userservice.ribbon.listOfServers: localhost:8888"
2122
})
22-
public class UserServiceConsumerTest {
23+
class UserServiceConsumerTest {
2324

24-
@Rule
25-
public PactProviderRuleMk2 stubProvider = new PactProviderRuleMk2("userservice", "localhost", 8888, this);
25+
@Autowired
26+
private UserClient userClient;
2627

27-
@Autowired
28-
private UserClient userClient;
28+
@Pact(state = "provider accepts a new person", provider = "userservice", consumer = "userclient")
29+
RequestResponsePact createPersonPact(PactDslWithProvider builder) {
30+
// @formatter:off
31+
return builder
32+
.given("provider accepts a new person")
33+
.uponReceiving("a request to POST a person")
34+
.path("/user-service/users")
35+
.method("POST")
36+
.willRespondWith()
37+
.status(201)
38+
.matchHeader("Content-Type", "application/json")
39+
.body(new PactDslJsonBody()
40+
.integerType("id", 42))
41+
.toPact();
42+
// @formatter:on
43+
}
2944

30-
@Pact(state = "provider accepts a new person", provider = "userservice", consumer = "userclient")
31-
public RequestResponsePact createPersonPact(PactDslWithProvider builder) {
32-
return builder
33-
.given("provider accepts a new person")
34-
.uponReceiving("a request to POST a person")
35-
.path("/user-service/users")
36-
.method("POST")
37-
.willRespondWith()
38-
.status(201)
39-
.matchHeader("Content-Type", "application/json")
40-
.body(new PactDslJsonBody()
41-
.integerType("id", 42))
42-
.toPact();
43-
}
45+
@Pact(state = "person 42 exists", provider = "userservice", consumer = "userclient")
46+
RequestResponsePact updatePersonPact(PactDslWithProvider builder) {
47+
// @formatter:off
48+
return builder
49+
.given("person 42 exists")
50+
.uponReceiving("a request to PUT a person")
51+
.path("/user-service/users/42")
52+
.method("PUT")
53+
.willRespondWith()
54+
.status(200)
55+
.matchHeader("Content-Type", "application/json")
56+
.body(new PactDslJsonBody()
57+
.stringType("firstName", "Zaphod")
58+
.stringType("lastName", "Beeblebrox"))
59+
.toPact();
60+
// @formatter:on
61+
}
4462

45-
@Pact(state = "person 42 exists", provider = "userservice", consumer = "userclient")
46-
public RequestResponsePact updatePersonPact(PactDslWithProvider builder) {
47-
return builder
48-
.given("person 42 exists")
49-
.uponReceiving("a request to PUT a person")
50-
.path("/user-service/users/42")
51-
.method("PUT")
52-
.willRespondWith()
53-
.status(200)
54-
.matchHeader("Content-Type", "application/json")
55-
.body(new PactDslJsonBody()
56-
.stringType("firstName", "Zaphod")
57-
.stringType("lastName", "Beeblebrox"))
58-
.toPact();
59-
}
6063

64+
@Test
65+
@PactTestFor(pactMethod = "createPersonPact")
66+
void verifyCreatePersonPact() {
67+
User user = new User();
68+
user.setFirstName("Zaphod");
69+
user.setLastName("Beeblebrox");
70+
IdObject id = userClient.createUser(user);
71+
assertThat(id.getId()).isEqualTo(42);
72+
}
6173

62-
@Test
63-
@PactVerification(fragment = "createPersonPact")
64-
public void verifyCreatePersonPact() {
65-
User user = new User();
66-
user.setFirstName("Zaphod");
67-
user.setLastName("Beeblebrox");
68-
IdObject id = userClient.createUser(user);
69-
assertThat(id.getId()).isEqualTo(42);
70-
}
71-
72-
@Test
73-
@PactVerification(fragment = "updatePersonPact")
74-
public void verifyUpdatePersonPact() {
75-
User user = new User();
76-
user.setFirstName("Zaphod");
77-
user.setLastName("Beeblebrox");
78-
User updatedUser = userClient.updateUser(42L, user);
79-
assertThat(updatedUser.getFirstName()).isEqualTo("Zaphod");
80-
assertThat(updatedUser.getLastName()).isEqualTo("Beeblebrox");
81-
}
74+
@Test
75+
@PactTestFor(pactMethod = "updatePersonPact")
76+
void verifyUpdatePersonPact() {
77+
User user = new User();
78+
user.setFirstName("Zaphod");
79+
user.setLastName("Beeblebrox");
80+
User updatedUser = userClient.updateUser(42L, user);
81+
assertThat(updatedUser.getFirstName()).isEqualTo("Zaphod");
82+
assertThat(updatedUser.getLastName()).isEqualTo("Beeblebrox");
83+
}
8284

8385
}
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
{
2+
"provider": {
3+
"name": "userservice"
4+
},
5+
"consumer": {
6+
"name": "userclient"
7+
},
8+
"interactions": [
9+
{
10+
"description": "a request to PUT a person",
11+
"request": {
12+
"method": "PUT",
13+
"path": "/user-service/users/42"
14+
},
15+
"response": {
16+
"status": 200,
17+
"headers": {
18+
"Content-Type": "application/json"
19+
},
20+
"body": {
21+
"firstName": "Zaphod",
22+
"lastName": "Beeblebrox"
23+
},
24+
"matchingRules": {
25+
"body": {
26+
"$.firstName": {
27+
"matchers": [
28+
{
29+
"match": "type"
30+
}
31+
],
32+
"combine": "AND"
33+
},
34+
"$.lastName": {
35+
"matchers": [
36+
{
37+
"match": "type"
38+
}
39+
],
40+
"combine": "AND"
41+
}
42+
},
43+
"header": {
44+
"Content-Type": {
45+
"matchers": [
46+
{
47+
"match": "regex",
48+
"regex": "application/json"
49+
}
50+
],
51+
"combine": "AND"
52+
}
53+
}
54+
}
55+
},
56+
"providerStates": [
57+
{
58+
"name": "person 42 exists"
59+
}
60+
]
61+
},
62+
{
63+
"description": "a request to POST a person",
64+
"request": {
65+
"method": "POST",
66+
"path": "/user-service/users"
67+
},
68+
"response": {
69+
"status": 201,
70+
"headers": {
71+
"Content-Type": "application/json"
72+
},
73+
"body": {
74+
"id": 42
75+
},
76+
"matchingRules": {
77+
"header": {
78+
"Content-Type": {
79+
"matchers": [
80+
{
81+
"match": "regex",
82+
"regex": "application/json"
83+
}
84+
],
85+
"combine": "AND"
86+
}
87+
},
88+
"body": {
89+
"$.id": {
90+
"matchers": [
91+
{
92+
"match": "integer"
93+
}
94+
],
95+
"combine": "AND"
96+
}
97+
}
98+
}
99+
},
100+
"providerStates": [
101+
{
102+
"name": "provider accepts a new person"
103+
}
104+
]
105+
}
106+
],
107+
"metadata": {
108+
"pactSpecification": {
109+
"version": "3.0.0"
110+
},
111+
"pact-jvm": {
112+
"version": "3.5.20"
113+
}
114+
}
115+
}

0 commit comments

Comments
 (0)