Gianluca Ciccarelli
11/22/2024, 2:08 PMTim Vahlbrock
11/25/2024, 7:29 AMsetupClassGraph
in many provider tests and wasn't able to find out whats the problem. Some research shows that instead of a specific package, the class gaph scan is performed on the whole namespace. Does anyone no anything about this?Martin Konir
11/28/2024, 1:55 PM@Pact
method for each provider and write a corresponding @Test-s
for each @Pact
method.
We are looking for a solution to avoid duplicating this code ( the @Pact
and @Test
methods) since the contract for each provider is the same.
The desired outcome is to have a single @Pact
definition and multiple @Test
methods for this one definition. However, when the tests are executed and successful, multiple contracts (the same contract but with different provider names) should be generated and uploaded to the PactBroker.
Is there a solution to achieve this, for example, by editing the mockserver in JUnit @AfterAll
?
According to the Pact JVM library rules:
• Each @Pact
can have only one provider name.
• Each @Pact
must be associated with a test methodRuth
11/29/2024, 11:45 AMarrayEachLike(examples: Int)
.
My example:
@Pact(consumer = CONSUMER, provider = PROVIDER)
RequestResponsePact pact(PactDslWithProvider builder) {
return builder
.uponReceiving("get cities")
.method("GET")
.path("/rest/cities")
.willRespondWith()
.status(200)
.body(
arrayEachLike(2)
.stringType("name", "Berlin")
)
.toPact()
}
I tried this, but I cannot give the number of examples I want to have here:
.body(
LambdaDsl.newJsonArray { rootArray: LambdaDslJsonArray ->
rootArray.`object` { object ->
object.stringType("name", "Berlin")
}
}.build()
)
What can I do instead to be able to put a number of examples in, but not a min/max size?
When there is a field with type array I found the .eachLike
method, but I cannot find anything for the root level.Ruud Welling
12/03/2024, 3:25 PMGitHub
12/03/2024, 11:06 PMGitHub
12/04/2024, 10:53 PMEric Deandrea
12/09/2024, 4:45 PM@Disabled
annotation..
org.junit.jupiter.api.condition.DisabledForJreRange
org.junit.jupiter.api.condition.DisabledIf
org.junit.jupiter.api.condition.DisabledIfEnvironmentVariable
org.junit.jupiter.api.condition.DisabledIfEnvironmentVariables
org.junit.jupiter.api.condition.DisabledIfSystemProperties
org.junit.jupiter.api.condition.DisabledIfSystemProperty
org.junit.jupiter.api.condition.DisabledInNativeImage
org.junit.jupiter.api.condition.DisabledOnJre
org.junit.jupiter.api.condition.DisabledOnOs
Ran Abitbul
12/11/2024, 7:56 AMPietro Di Bello
12/17/2024, 11:23 AMmiłosz Mazurek
01/06/2025, 3:08 PM@Provider('employee_spock_provider')
@WebMvcTest
class EmployeeControllerMvcSpec extends PactMvcTest {
@Autowired
MockMvc mockMvc
@Shared
ProviderInfo serviceProvider
ProviderVerifier verifier
@SpringBean
EmployeeService employeeService = Mock()
def setupSpec() {
serviceProvider = new ProviderInfo("employee_spock_provider")
serviceProvider.hasPactsFromPactBroker("<http://localhost:9292>")
}
def setup() {
verifier = new ProviderVerifier()
setupMockMvcTest(mockMvc, EmployeeControllerMvcSpec.class, this)
}
def 'verify contract for #consumer for interaction get all employees'() {
given:
employeeService.getEmployees() >> List.of(anEmployee(), anEmployee2())
expect:
verifyPactForInteraction(verifier, consumer, 'get all employees')
where:
consumer << serviceProvider.consumers
}
}
miłosz Mazurek
01/06/2025, 3:09 PMclass PactMvcTest extends Specification {
@Shared
private MockMvcTarget mockMvcTarget
def setupSpec() {
mockMvcTarget = new MockMvcTarget()
}
void setupMockMvcTest(MockMvc mockMvc, Class<?> clazz, Object testClass) {
mockMvcTarget.setMockMvc(mockMvc)
mockMvcTarget.setTestClass(new TestClass(clazz), testClass)
}
void verifyPactForInteraction(ProviderVerifier verifier, ConsumerInfo consumer, String description) {
PactSource pactSource = consumer.getPactSource()
List<Interaction> interactions = verifier.pactReader.loadPact(consumer.getPactSource()).getInteractions()
Interaction interaction = Stream.ofNullable(interactions)
.flatMap(Collection::stream)
.filter(it -> it.getDescription().equals(description))
.findFirst()
.orElseGet (null)
mockMvcTarget.testInteraction(consumer.getName(), interaction, pactSource, [:], false)
}
}
ludorival
01/11/2025, 11:40 AMJonathan Chambers
01/14/2025, 12:54 AMRuth
01/16/2025, 11:17 AM@Pact(consumer = CONSUMER, provider = PROVIDER)
RequestResponsePact provider(PactDslWithProvider builder) {
return builder
.uponReceiving("get")
.method("GET")
.headers("accept", "application/json, application/*+json")
.path("/test")
.willRespondWith()
.status(200)
.toPact()
}
I migrated it to look like this:
@Pact(consumer = CONSUMER, provider = PROVIDER)
V4Pact provider(PactBuilder builder) {
return builder
.expectsToReceiveHttpInteraction("get") { httpBuilder ->
httpBuilder
.withRequest { httpRequestBuilder ->
httpRequestBuilder
.path("/test")
.method("GET")
.headers("accept", "application/json, application/*+json")
}
.willRespondWith { httpResponseBuilder ->
httpResponseBuilder.status(200)
}
}
.toPact()
}
but now I get this error message from Pact:
2025-01-16 11:41:50,475 [HTTP-Dispatcher] ERROR a.c.d.p.c.BaseMockServer$Companion - PartialRequestMatch: get:
Expected header 'accept' to have value 'application/json' but was 'application/json, application/*+json'
Expected header 'accept' to have value 'application/*+json' but was ''
I am very confused as the signature of the method headers
I am using shows it as a value:String. I also tried the .header
method, but I still get the same error.
Any idea what I can do?Nuno Domingues
01/22/2025, 9:47 AMTom Lopez
01/22/2025, 4:04 PMRomain Létendart
01/31/2025, 4:56 PMTim Vahlbrock
02/10/2025, 8:01 AMVictor Vargas
02/10/2025, 9:51 AM@TestTemplate
@ExtendWith(PactVerificationInvocationContextProvider.class)
public void pactVerificationTestTemplate(PactVerificationContext context) {
context.verifyInteraction();
}
If not, what is the recommended way of doing so?
Thanks in advance 🤗Victor Vargas
02/10/2025, 2:53 PM[WARNING] Rule 2: org.apache.maven.plugins.enforcer.DependencyConvergence failed with message:
Failed while enforcing releasability the error(s) are [
Dependency convergence error for org.apache.tika:tika-core:2.9.1 paths to dependency are:
+-com.myproject:1.55.8-SNAPSHOT
+-au.com.dius.pact.provider:spring:4.6.16
+-au.com.dius.pact.provider:junit:4.6.16
+-au.com.dius.pact:provider:4.6.16
+-au.com.dius.pact.core:matchers:4.6.16
+-org.apache.tika:tika-core:2.9.1
and
+-com.myproject:1.55.8-SNAPSHOT
+-au.com.dius.pact.provider:spring:4.6.16
+-au.com.dius.pact.provider:junit:4.6.16
+-au.com.dius.pact:provider:4.6.16
+-io.pact.plugin.driver:core:0.5.1
+-org.apache.tika:tika-core:2.9.2
and
+-com.myprojecti:1.55.8-SNAPSHOT
+-au.com.dius.pact.provider:spring:4.6.16
+-au.com.dius.pact.provider:junit:4.6.16
+-au.com.dius.pact.core:model:4.6.16
+-org.apache.tika:tika-core:2.9.1
Spencer
02/11/2025, 3:34 PMJuan Park
02/12/2025, 3:25 PM"interactions": [
{
"description": "List bundles request",
"interactionMarkup": {
"markup": [...]
},
"key": "5050049c",
"pending": false,
[...]
"metadata": {
"pact-jvm": {
"version": "4.6.14"
},
"pactSpecification": {
"version": "4.0"
},
}
GitHub
02/14/2025, 12:56 AMHaritima Haritima
02/18/2025, 11:40 AMExecutor.closeIdleConnections();
with @afterEach tests but that doesnt work.
Can someone please help with alternative solution to tear down the connection after each tests (edited)Denys
02/18/2025, 3:46 PM@ExtendWith(PactConsumerTestExt.class)
@PactTestFor(providerName = "P01823-TS-Trade-Store", pactVersion = PactSpecVersion.V4, providerType = ProviderType.SYNCH_MESSAGE)
class GetTradesByFilterProductTypeFXFWDTest {
ManagedChannel channel;
@BeforeEach
void setUp(MockServer mockServer) {
System.setProperty("pact_do_not_track", "true");
}
////////////////// 1. GetTradesByFilter product types
@Pact(consumer = "P01819-ipa-mi")
public V4Pact tradesByFilterProductTypeFXFWD(PactBuilder builder) {
return builder
.usingPlugin("protobuf")
.expectsToReceive("a get trade by filter request", "core/interaction/synchronous-message")
.with(Map.of(
"pact:proto", filePath("proto/tsServiceV2.proto"),
"pact:content-type", "application/grpc",
"pact:proto-service", "TradeStoreService/GetTradesByFilter",
"pact:protobuf-config", Map.of(
"additionalIncludes",
List.of(filePath("proto/tsService.proto"))),
// Details on the request message
"request", Map.of(
"productTypes",
Map.of("value",
"matching(equalTo, 'FXFWD')")),
// Details on the response
"response",
Map.of("trade_key",
Map.of("product_type", "matching(equalTo, 'FXFWD')")))
).toPact();
}
@Test
@PactTestFor(pactMethod = "tradesByFilterProductTypeFXFWD")
@MockServerConfig(implementation = MockServerImplementation.Plugin, registryEntry = "protobuf/transport/grpc")
void testTradesByFilterProductTypeFXFWD(MockServer mockServer, V4Interaction.SynchronousMessages interaction) throws InvalidProtocolBufferException, InterruptedException {
boolean success = false;
ManagedChannel channel = ManagedChannelBuilder.forTarget("127.0.0.1:" + mockServer.getPort())
.usePlaintext()
.build();
try {
TradeStoreServiceGrpc.TradeStoreServiceBlockingStub stub = TradeStoreServiceGrpc.newBlockingStub(channel);
ts.api.TsServiceV2.TradeFilter tradeFilter = ts.api.TsServiceV2.TradeFilter.parseFrom(interaction.getRequest().getContents().getValue());
Iterator<TsService.Trade> responseTrade = stub.getTradesByFilter(tradeFilter);
assertThat(responseTrade).as("getTradeByFilter is null").isNotNull();
} finally {
if (!success) {
channel.awaitTermination(10, TimeUnit.SECONDS);
channel.shutdown();
}
}
}
@Pact(consumer = "P01819-ipa-mi")
public V4Pact tradesByFilterProductTypeFXFWDONE(PactBuilder builder) {
return builder
.usingPlugin("protobuf")
.expectsToReceive("a get trade by filter request", "core/interaction/synchronous-message")
.with(Map.of(
"pact:proto", filePath("proto/tsServiceV2.proto"),
"pact:content-type", "application/grpc",
"pact:proto-service", "TradeStoreService/GetTradesByFilter",
"pact:protobuf-config", Map.of(
"additionalIncludes",
List.of(filePath("proto/tsService.proto"))),
// Details on the request message
"request", Map.of(
"productTypes",
Map.of("value",
"matching(equalTo, 'FXFWD')")),
// Details on the response
"response",
Map.of("trade_key",
Map.of("product_type", "matching(equalTo, 'FXFWD')")))
).toPact();
}
@Test
@PactTestFor(pactMethod = "tradesByFilterProductTypeFXFWDONE")
@MockServerConfig(implementation = MockServerImplementation.Plugin, registryEntry = "protobuf/transport/grpc")
void testTradesByFilterProductTypeFXFWDONE(MockServer mockServer, V4Interaction.SynchronousMessages interaction) throws InvalidProtocolBufferException, InterruptedException {
boolean success = false;
ManagedChannel channel = ManagedChannelBuilder.forTarget("127.0.0.1:" + mockServer.getPort())
.usePlaintext()
.build();
try {
TradeStoreServiceGrpc.TradeStoreServiceBlockingStub stub = TradeStoreServiceGrpc.newBlockingStub(channel);
ts.api.TsServiceV2.TradeFilter tradeFilter = ts.api.TsServiceV2.TradeFilter.parseFrom(interaction.getRequest().getContents().getValue());
Iterator<TsService.Trade> responseTrade = stub.getTradesByFilter(tradeFilter);
assertThat(responseTrade).as("getTradeByFilter is null").isNotNull();
} finally {
if (!success) {
channel.awaitTermination(10, TimeUnit.SECONDS);
channel.shutdown();
}
}
}
}
After running all class I have an error:
2025-02-18 17:34:46,081 ERROR [main] [:] io.pact.plugins.jvm.core.DefaultPluginManager: Failed to initialise the plugin
io.grpc.StatusRuntimeException: UNAVAILABLE: io exception
at io.grpc.stub.ClientCalls.toStatusRuntimeException(ClientCalls.java:351)
at io.grpc.stub.ClientCalls.getUnchecked(ClientCalls.java:332)
at io.grpc.stub.ClientCalls.blockingUnaryCall(ClientCalls.java:174)
at io.pact.plugin.PactPluginGrpc$PactPluginBlockingStub.initPlugin(PactPluginGrpc.java:641)
at io.pact.plugins.jvm.core.DefaultPluginManager.initPlugin$lambda$37(PluginManager.kt:913)
at io.pact.plugins.jvm.core.DefaultPactPlugin.withGrpcStub(PluginManager.kt:267)
at io.pact.plugins.jvm.core.DefaultPluginManager.initPlugin(PluginManager.kt:913)
at io.pact.plugins.jvm.core.DefaultPluginManager.tryInitPlugin(PluginManager.kt:892)
at io.pact.plugins.jvm.core.DefaultPluginManager.initialisePlugin(PluginManager.kt:866)
at io.pact.plugins.jvm.core.DefaultPluginManager.loadPlugin(PluginManager.kt:419)
at au.com.dius.pact.consumer.dsl.PactBuilder.usingPlugin(PactBuilder.kt:113)
at au.com.dius.pact.consumer.dsl.PactBuilder.usingPlugin$default(PactBuilder.kt:110)
at au.com.dius.pact.consumer.dsl.PactBuilder.usingPlugin(PactBuilder.kt)
at com.ing.ipami.pact.product_type.GetTradesByFilterProductTypeFXFWDTest.tradesByFilterProductTypeFXFWDONE(GetTradesByFilterProductTypeFXFWDTest.java:101)
Caused by: io.grpc.netty.shaded.io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: getsockopt: /[00000001]52748
Caused by: java.net.ConnectException: Connection refused: getsockopt
Process finished with exit code 0
protobuf plugin V 0.5.4 is installed on my laptop
Do you have any ideas why after running tested class PACT framework generated only one tested method inside contract/.json file?
Thanksvicky
02/19/2025, 12:19 PMHaritima Haritima
02/19/2025, 5:01 PMBas Dijkstra
02/24/2025, 7:25 AMShrinivas Khawase
02/24/2025, 8:52 AMau.com.dius.pact.consumer:junit Version 4.6.14
but we often get the error mentioned below which blocks our pipeline , has anyone else faced this ?Its not consistent but occurs randomly
cc @Sitaram Appalla @Ramesh Kumar
Failed to transform java-semver-0.9.0.jar (com.github.zafarkhaja:java-semver:0.9.0) to match attributes {artifactType=android-classes-jar, org.gradle.category=library, org.gradle.libraryelements=jar, org.gradle.status=release, org.gradle.usage=java-runtime}.
> Could not find java-semver-0.9.0.jar (com.github.zafarkhaja:java-semver:0.9.0).
Searched in the following locations:
<https://jitpack.io/com/github/zafarkhaja/java-semver/0.9.0/java-semver-0.9.0.jar>