Bartosz Kwapisz
05/27/2024, 7:12 PMpactVerify
gradle task (with newest gradle plugin), but it doesn't run my tests defined as junit5 extension - like here:
@Provider("myAwesomeService")
@PactFolder("pacts")
public class ContractVerificationTest {
@TestTemplate
@ExtendWith(PactVerificationInvocationContextProvider.class)
void pactVerificationTestTemplate(PactVerificationContext context) {
context.verifyInteraction();
}
}
It fetched pacts from the broker defined in my pact-broker, but then the verification failed because my test setup was not run.
On the other hand, I'm able to run them manually from Intellij
Should it work correctly?
Could you please share your configuration that allows running pactVerify
task with junit runner?Tim Vahlbrock
05/28/2024, 7:59 AMBartosz Kwapisz
05/28/2024, 8:34 AMJason Sunde
05/28/2024, 3:23 PMTim Vahlbrock
05/29/2024, 8:58 AMAyush Raivari
05/30/2024, 1:44 PMGitHub
05/31/2024, 5:02 AMTim Vahlbrock
06/03/2024, 7:09 AMbody.array("theArrayKey").stringType().closeArray()
, the array is expected to have a length of 1 in the verification. However, I can't use minArrayLike
either, because that will only support Objects or Arrays (The method Signature allows passing of PactDslPart, but PactDslJsonRootValue would be ignored in the internal processing as not being one of PactDslJsonBody or PactDslJsonArray. I guess PactDslRootValue isn't intended for usage on fields anyway). I would expect how to define variable sized arrays to be documented on https://docs.pact.io/implementation_guides/jvm/consumer, but can't find it there. Where do I need to look?s1apped
06/03/2024, 7:42 AMPK
06/04/2024, 3:44 AMTim Vahlbrock
06/04/2024, 11:16 AM@PactTestFor
method each time? I have 10 Message Types on the same Kafka Topic, as far as I have understood so far, I can either
1. implement a @PactTestFor method for each of them, with the only change being a different pactMethod
and a different test name or
2. have one @PactTestFor
with all in pactMethods
but little way of knowing which of the messages failed to be processed besides the exception thrown and the index of the loop over the messages.
I'm thinking of something similar to the @TestTemplate
Style of the Provider Tests with the Pact name being the test name.Riya Talwar
06/05/2024, 2:04 PMUnexpected character 'EOI(null)' at position '3', expecting '[DOT]'
at app//com.github.zafarkhaja.semver.VersionParser.consumeNextCharacter(VersionParser.java:516)
at app//com.github.zafarkhaja.semver.VersionParser.parseVersionCore(VersionParser.java:288)
at app//com.github.zafarkhaja.semver.VersionParser.parseValidSemVer(VersionParser.java:255)
at app//com.github.zafarkhaja.semver.VersionParser.parseValidSemVer(VersionParser.java:195)
at app//com.github.zafarkhaja.semver.Version.valueOf(Version.java:265)
at app<//au.com>.dius.pact.core.model.DefaultPactReader.loadPact(PactReader.kt:177)
at app<//au.com>.dius.pact.provider.junit.loader.PactBrokerLoader.loadPact(PactBrokerLoader.kt:203)
at app<//au.com>.dius.pact.provider.junit.loader.PactBrokerLoader.loadPactsForProvider(PactBrokerLoader.kt:155)
at app<//au.com>.dius.pact.provider.junit.loader.PactBrokerLoader.load(PactBrokerLoader.kt:92)
at app<//au.com>.dius.pact.provider.junit.PactRunner.initialize(PactRunner.kt:85)
at app<//au.com>.dius.pact.provider.junit.PactRunner.getChildren(PactRunner.kt:140)
at app//org.junit.runners.ParentRunner.getFilteredChildren(ParentRunner.java:534)
at app//org.junit.runners.ParentRunner.getDescription(ParentRunner.java:400)
at app//org.junit.runners.model.RunnerBuilder.configureRunner(RunnerBuilder.java:81)
at app//org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:72)
Josilene Fernandes
06/12/2024, 6:49 PMAlan Boshier
06/13/2024, 3:09 PMtimestamp: timestamp('dd-MM-yyyy HH:mm:ss', '03-07-2019 04:00:23')
The provider StateChangeHandler magics up a "random" value for this response (based on LocalDateTime.now()
).
With the provider running pact-jvm version 4.6.10 the contract is verified as expected, but if the provider runs pact-jvm version 4.2.14 the pact fails to verify with the error:
body: $.timestamp Expected "13-06-2024 03:56:35" (String) to equal "03-07-2019 04:00:23" (String)
which seems to fail because the verifier is unexpectedly doing an equality test rather than a type/format test on the returned field value.
Was there some change between 4.2 and 4.6 in pact-jvm which would explain this discrepancy?
I don't know if its related, but I noticed that the generated JSON pact format on the consumer side for timestamp expectations underwent some kind of change between v10 and v12
v10: { "format": "dd-MM-yyyy HH:mm:ss", "match": "timestamp" }
v12: { "format": "dd-MM-yyyy HH:mm:ss", "match": "datetime" }
Paolo Laurenti
06/13/2024, 3:09 PMAshok Elumalai
06/17/2024, 8:34 AMorg.junit.runners.model.InitializationError
at au.com.dius.pact.provider.junit.PactRunner.initialize(PactRunner.kt:115)
at au.com.dius.pact.provider.junit.PactRunner.getChildren(PactRunner.kt:143)
at org.junit.runners.ParentRunner.getFilteredChildren(ParentRunner.java:426)
at org.junit.runners.ParentRunner.getDescription(ParentRunner.java:351)
at com.intellij.junit4.JUnit4IdeaTestRunner.getDescription(JUnit4IdeaTestRunner.java:79)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:51)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Can someone guide?
I am using pact 4.1.0
Janna Loeffler
06/17/2024, 6:40 PMGiven test a valid campaign
push of a valid campaign
returns a response which
has status code (FAILED)
has a matching body (OK)
status: expected a stats of 201 but was 404
I have my provider up and running locally on my machine at: <http://localhost:8082/>
Im trying to test the endpoint: POST <http://localhost:8082/campaigns/138993/push>
(I can push a payload to this endpoint with Postman and it returns a 201 status)
I have a consumer contract up on PactFlow. Running with: mvn pact:verify
Any help is greatly appreciated!
Here is my test:
@ExtendWith(SpringExtension.class)
@Provider("malibu")
class MalibuPactTest{
@LocalServerPort
int port = 8082;
@BeforeEach
public void setUp(PactVerificationContext context){
HttpTestTarget target = new HttpTestTarget("localhost", port, "/campaigns/138993/push";
context.setTarget(target);
}
@TestTemplate
@ExtendWith(PactVerificationInvocationContextProvider.class)
public void pactVerificationTestTemplate(PactVerificationContext context){
context.verifyInteraction();
}
@State("test a valid campaign")
public void testValidCampaign() throws IOException{
}
}
Alan Boshier
06/18/2024, 4:49 PMjava.lang.NoSuchMethodError: 'java.lang.Object kotlin.collections.CollectionsKt.maxWithOrNull(java.lang.Iterable, java.util.Comparator)'
My pom was declaring dependencies au.com.dius.pact.provider:junit5spring:4.6.10
and au.com.dius.pact.consumer:junit5:4.6.10
- no explicit kotlin dependencies and no other dependencies that pull in kotlin other than these 2.
Adding an explicit dependency to my pom org.jetbrains.kotlin:kotlin-stdlib:1.7.22
cures the problem, but should this be necessary?Stephen Bell
06/18/2024, 10:27 PMSaloni Udani
06/19/2024, 5:54 AMError retrieving matrix. PactBroker::Client::Hal::ErrorResponseReturned - Error making request to <https://pact-poc.pactflow.io/matrix> status=400 {"errors":["Pacticipant bdct-pactflow-consumer not found"]}
Ruud Welling
06/19/2024, 8:58 AMDelivered
but it could make sense to have a consumer test that verified that it can parse other status values.
If we set up a provider state, would it be possible to execute the same test multiple times with different state variants, so that all of these can be verified with the contract?GitHub
06/20/2024, 2:04 AMGiulio Giovannini
06/20/2024, 3:04 PM@WebMvcTest
and I pass the controller class to the MockMvcTestTarget
like so:
MyController sut = new MyController();
MockMvcTestTarget testTarget = new MockMvcTestTarget();
testTarget.setControllers(sut);
context.setTarget(testTarget);
So, this works well when the contract contains interaction served by the controller I am instantiating. How do I verify a contract that contains multiple interactions for other controllers? The above test will send ALL interaction to the single controller I am instantiating so it will fail as some are not covered there.
Is there a way to only verify a subset of the interactions? If verification is split in multiple subclasses will a single overall verification result be sent to the broker?
I can not bring up the entire application unfortunately.Jonathan Chambers
06/20/2024, 4:38 PM@PactConsumerTest
@PactTestFor(providerName = "provider", pactVersion = PactSpecVersion.V4)
@MockServerConfig(hostInterface = "localhost", port="8080")
@SpringBootTest(properties = { "cxf.jaxrs.client.address = "<http://localhost:8080>" })
This works fine. However I would like to use an ephemeral port - i.e. a port which is guaranteed (more or less) to be available.
So either
• generate the port using something like TestSocketUtils.findAvailableTcpPort()
• or get Pact to generate the port number on the MockServer and then set the cxf.jaxrs.client.address to the address containing that port.
If I generate the port number using TestSocketUtils.findAvailableTcpPort(), I can set cxf.jaxrs.client.address with this port before the context loads - but I'm struggling to set this on the MockServerConfig.
In JUnit 4 there was support for this via
static final int providerPort = TestSocketUtils.findAvailableTcpPort;
@DynamicPropertySource
static void registerProperties(DynamicPropertyRegistry registry) {
registry.add("cxf.jaxrs.client.address", () ->
String.format("<http://localhost>:%d/authenticator", providerPort)
}
@Rule
public PactProviderRule mockProvider = new PactProviderRule("provider", "localhost", providerPort, this);
But using the latest PACT (4.6.10) and Junit5 the MockServer seems to ignore the parameters specified in PactProviderRule.
If I try and use the port number generated when MockServer is created, then by then its too late and I can't inject this port number into cxf.jaxrs.client.address before the Spring context loads. I only know how to get a handle on this from either params on methods annotated with @Test or @BeforeEach and at that point it is too late to inject the port number into cxf.jaxrs.client.address.
I hope you understand the predicament I'm in, can you suggest a way to use ephemeral ports that can be used by both MockServer and Spring Boot property injection?
Any help would be appreciated.Neha Munjal
06/22/2024, 12:48 AMNeha Munjal
06/24/2024, 8:53 PM<dependency>
<groupId>au.com.dius.pact.provider</groupId>
<artifactId>junit5</artifactId>
<version>4.6.5</version>
<scope>test</scope>
</dependency>
We now have a use case wherein the current Provider (HTTP) also provides support for async use case, and has the handler or consumer implementation to consume the message. SO this would mean it takes the role of PACT consumer.
What dependency can we use here so that the same microservice can have both the provider and consumer roles.Malgorzata
06/26/2024, 10:00 AM{
"area": {
"type": "MultiPolygon",
"coordinates": [
[
[
[
40,
40
],
[
20,
45
],
[
45,
30
],
[
40,
40
]
]
]
]
}
}
Coordinates are nested few times array. I managed to do it with PactDslJsonBody
.body(new PactDslJsonBody()
.object("area")
.stringMatcher("type", "MultiPolygon")
.eachArrayLike("coordinates")
.eachArrayLike(3)
.decimalType(40.0)
.decimalType(40.0)
.closeArray()
.closeArray()
.closeArray()
.closeArray()
.closeObject())
Is there a way to do it with LambdaDSL? I see only array od objects and wasn’t able to get same as
.eachArrayLike("coordinates")
.eachArrayLike(3)
Janna Loeffler
06/26/2024, 3:06 PM@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT,
properties = {
"server.port=8082"
})
@ExtendWith(SpringExtension.class)
@PactBroker(url="<https://inmarket.pactflow.io>", authentication = @PactBrokerAuth(token = "<token>"))
@Provider("malibu")
class MalibuPactTest {
@LocalServerPort
int port;
@BeforeEach
public void setUp(PactVerificationContext context) {
context.setTarget(new HttpTestTarget("localhost", port));
}
@TestTemplate
@ExtendWith(PactVerificationInvocationContextProvider.class)
public void pactVerificationTestTemplate(PactVerificationContext context) {
context.verifyInteraction();
}
@State("test a valid campaign")
public void testValidCampaign() throws IOException {
}
}
Log:
[DEBUG] http-outgoing-3 >> "POST /campaigns/138993/push HTTP/1.1[\r][\n]"
[DEBUG] http-outgoing-3 >> "Content-Type: application/json[\r][\n]"
[DEBUG] http-outgoing-3 >> "Accept-Encoding: gzip, x-gzip, deflate[\r][\n]"
[DEBUG] http-outgoing-3 >> "Content-Length: 266[\r][\n]"
[DEBUG] http-outgoing-3 >> "Host: localhost:8080[\r][\n]"
[DEBUG] http-outgoing-3 >> "Connection: keep-alive[\r][\n]"
[DEBUG] http-outgoing-3 >> "User-Agent: Apache-HttpClient/5.2.1 (Java/21.0.3)[\r][\n]"
[DEBUG] http-outgoing-3 >> "[\r][\n]"
The endpoint Im trying to hit is:
<https://localhost:8082/campaigns/138993/push>
Luciano Nery
06/26/2024, 3:17 PMFailed to fetch the root HAL document
Before that, application shows this message: "Fetching: /"
When I use preemptive authentication, I can see this error ex-0000000001 Basic{} authentication error: User credentials not set
, but the other one still happens
I'm setting the credentials this way:
systemProperty("pactbroker.auth.username", System.getenv("PACT_USER"))
systemProperty("pactbroker.auth.password", System.getenv("PACT_PASSWORD"))
systemProperty("pactbroker.url", "<https://blablabla>") // I cannot share the real url
systemProperty("pactbroker.auth.scheme", "basic")
The environment variables are there in the pipelineRuud Welling
06/27/2024, 1:56 PMafterAll
method of the extension fails because of the following error:
au.com.dius.pact.core.model.InvalidPactException: Cannot merge pacts as they are not compatible - Pact types different: 'MessagePact' can not be assigned to 'RequestResponsePact'
at au.com.dius.pact.core.model.DefaultPactWriter.writePact(PactWriter.kt:95)
at au.com.dius.pact.core.model.BasePact.write(BasePact.kt:24)
at au.com.dius.pact.consumer.junit5.PactConsumerTestExt.afterAll(PactConsumerTestExt.kt:709)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
I tried using V4 pacts for this, and then it does work fine, but since the python SDK for the provider does not support V4 yet this is not an option for us.