Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public ProductServiceImpl(RestTemplate restTemplate, @Value("${product.api.base-

@Override
public ProductDTO getProductById(Integer id) {
String url = baseUrl + "/products/{id}";
String url = baseUrl + "/product-api/products/{id}";
return restTemplate.getForObject(url, ProductDTO.class, id);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import au.com.dius.pact.core.model.PactSpecVersion;
import au.com.dius.pact.core.model.RequestResponsePact;
import au.com.dius.pact.core.model.annotations.Pact;
import au.com.dius.pact.core.model.annotations.PactDirectory;
import auftragsverwaltung.infrastructure.ProductDTO;
import auftragsverwaltung.infrastructure.ProductServiceImpl;
import org.junit.jupiter.api.Test;
Expand All @@ -22,20 +23,22 @@

@ExtendWith(PactConsumerTestExt.class)
@PactTestFor(providerName = "product-backend", pactVersion = PactSpecVersion.V3)
@PactDirectory("../pacts")
class ProductConsumerPactTest {

@Pact(consumer = "order-backend", provider = "product-backend")
public RequestResponsePact getProduct_ok(PactDslWithProvider builder) {
Integer anyId = 1;
PactDslJsonBody body = new PactDslJsonBody()
.numberType("id", 1)
.numberType("id", anyId)
.stringType("name", "TestProduct")
.numberType("price", 19.99)
.stringMatcher("currency", "EUR|USD");

return builder
.given("product 1 exists")
.uponReceiving("GET /products/1")
.path("/products/1")
.given("product exists", Map.of("id", anyId))
.uponReceiving("GET ein Product das existiert")
.pathFromProviderState("/product-api/products/${id}", "/product-api/products/%d".formatted(anyId))
.method("GET")
.willRespondWith()
.status(200)
Expand All @@ -46,10 +49,11 @@ public RequestResponsePact getProduct_ok(PactDslWithProvider builder) {

@Pact(consumer = "order-backend", provider = "product-backend")
public RequestResponsePact getProduct_notFound(PactDslWithProvider builder) {
Integer notFoundId = 999;
return builder
.given("product 999 not found")
.uponReceiving("GET /products/999")
.path("/products/999")
.given("product not found")
.uponReceiving("GET eine Produktnummer die nicht existiert")
.pathFromProviderState("/product-api/products/${notFoundId}", "/product-api/products/%d".formatted(notFoundId))
.method("GET")
.willRespondWith()
.status(404)
Expand Down
119 changes: 119 additions & 0 deletions pacts/order-backend-product-backend.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
{
"consumer": {
"name": "order-backend"
},
"interactions": [
{
"description": "GET ein Product das existiert",
"providerStates": [
{
"name": "product exists",
"params": {
"id": 1
}
}
],
"request": {
"generators": {
"path": {
"dataType": "STRING",
"expression": "/product-api/products/${id}",
"type": "ProviderState"
}
},
"method": "GET",
"path": "/product-api/products/1"
},
"response": {
"body": {
"currency": "EUR",
"id": 1,
"name": "TestProduct",
"price": 19.99
},
"generators": {
"body": {
"$.currency": {
"regex": "EUR|USD",
"type": "Regex"
}
}
},
"headers": {
"Content-Type": "application/json"
},
"matchingRules": {
"body": {
"$.currency": {
"combine": "AND",
"matchers": [
{
"match": "regex",
"regex": "EUR|USD"
}
]
},
"$.id": {
"combine": "AND",
"matchers": [
{
"match": "number"
}
]
},
"$.name": {
"combine": "AND",
"matchers": [
{
"match": "type"
}
]
},
"$.price": {
"combine": "AND",
"matchers": [
{
"match": "number"
}
]
}
}
},
"status": 200
}
},
{
"description": "GET eine Produktnummer die nicht existiert",
"providerStates": [
{
"name": "product not found"
}
],
"request": {
"generators": {
"path": {
"dataType": "STRING",
"expression": "/product-api/products/${notFoundId}",
"type": "ProviderState"
}
},
"method": "GET",
"path": "/product-api/products/999"
},
"response": {
"status": 404
}
}
],
"metadata": {
"pact-jvm": {
"version": "4.6.17"
},
"pactSpecification": {
"version": "3.0.0"
}
},
"provider": {
"name": "product-backend"
}
}
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<properties>
<spring.boot.version>3.5.6</spring.boot.version>
<java.version>21</java.version>
<pact.version>4.6.11</pact.version>
<pact.version>4.6.17</pact.version>
</properties>

<modules>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@
import produktkatalog.infrastructure.ProductService;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Map;
import java.util.Optional;

import static org.mockito.Mockito.when;
import static produktkatalog.domain.Product.CurrencyCode.EUR;

@Provider("product-backend")
@Consumer("order-backend")
@PactFolder("../order-backend/target/pacts")
@PactFolder("../pacts")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = ProductApp.class)
@ExtendWith(PactVerificationSpring6Provider.class)
class PactProviderVerificationTest {
Expand All @@ -41,18 +41,20 @@ class PactProviderVerificationTest {

@BeforeEach
void setup(@NotNull PactVerificationContext ctx) {
ctx.setTarget(new HttpTestTarget("localhost", port, "/product-api"));
ctx.setTarget(new HttpTestTarget("localhost", port));
}

@State("product 1 exists")
void setupUpProductExists() {
when(productService.getProductById(1))
.thenReturn(Optional.of(new Product(1, "TestProduct", new BigDecimal("19.99"), EUR)));
@State("product exists")
void setupUpProductExists(Map<String, Object> params) {
Integer id = Integer.valueOf(params.getOrDefault("id", 1).toString());
when(productService.getProductById(id))
.thenReturn(Optional.of(new Product(id, "TestProduct", new BigDecimal("19.99"), EUR)));
}

@State("product 999 not found")
void setUpProductNotFound() {
when(productService.getProductById(999))
@State("product not found")
void setUpProductNotFound(Map<String, Object> params) {
Integer id = Integer.valueOf(params.getOrDefault("id", 1).toString());
when(productService.getProductById(id))
.thenReturn(Optional.empty());
}

Expand All @@ -61,14 +63,4 @@ void setUpProductNotFound() {
void verify(PactVerificationContext ctx) {
ctx.verifyInteraction();
}


private static Integer asInt(Object value) {
if (value instanceof Integer i) return i;
if (value instanceof Long l) return l.intValue();
if (value instanceof BigInteger bi) return bi.intValue();
if (value instanceof Number n) return n.intValue();
return Integer.parseInt(String.valueOf(value));
}

}

This file was deleted.