Julián Álvarez
01/20/2023, 10:38 AMIvan Mikhalka
01/21/2023, 2:30 PMpath/to/endpoint/userId/12345 and then replace it on the fly.
    When storing pact file locally, we used to use sed for replacing placeholder with actual id, like sed s/12345/$ACTUAL_USERID/g , but it’s not the case when switching to pact broker.
    Could this be done via requestFilter from plugin or somehow else?
    I know it’s not the best practice, but we need some workaround for nowOnur
01/23/2023, 1:06 PM<dependency>
    <groupId>au.com.dius.pact.provider</groupId>
    <artifactId>junit5</artifactId>
    <version>4.4.4</version>
    <exclusions>
        <exclusion>
            <groupId>io.ktor</groupId>
            <artifactId>ktor-network-tls-certificates</artifactId>
        </exclusion>
        <exclusion>
            <groupId>io.ktor</groupId>
            <artifactId>ktor-server-netty</artifactId>
        </exclusion>
        <exclusion>
            <groupId>au.com.dius.pact.core</groupId>
            <artifactId>model</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>au.com.dius.pact.consumer</groupId>
    <artifactId>junit5</artifactId>
    <version>4.4.4</version>
    <scope>test</scope>
    <exclusions>
        <exclusion>
            <groupId>io.ktor</groupId>
            <artifactId>ktor-network-tls-certificates</artifactId>
        </exclusion>
        <exclusion>
            <groupId>io.ktor</groupId>
            <artifactId>ktor-server-netty</artifactId>
        </exclusion>
        <exclusion>
            <groupId>au.com.dius.pact.core</groupId>
            <artifactId>model</artifactId>
        </exclusion>
    </exclusions>
</dependency>
If I do not exclude any of these libraries, I am facing the below problem when I debug the tests in IntelliJ. This happens only for debugging, not running the tests.
Connected to the target VM, address: ‘127.0.0.1:52632’, transport: ‘socket’
Internal Error occurred.
org.junit.platform.commons.JUnitException: TestEngine with ID ‘junit-jupiter’ failed to discover tests
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverEngineRoot(EngineDiscoveryOrchestrator.java:160)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverSafely(EngineDiscoveryOrchestrator.java:132)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:107)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discover(EngineDiscoveryOrchestrator.java:78)
	at org.junit.platform.launcher.core.DefaultLauncher.discover(DefaultLauncher.java:110)
	at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
	at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
	at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
	at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:57)
	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)
Caused by: org.junit.platform.commons.JUnitException: MethodSelector [className = ‘com.emirates.ocsl.skeleton.ct.tests.SkeletonCT’, methodName = ‘iGetResponseSuccessfully’, methodParameterTypes = ‘’] resolution failed
	at org.junit.platform.launcher.listeners.discovery.AbortOnFailureLauncherDiscoveryListener.selectorProcessed(AbortOnFailureLauncherDiscoveryListener.java:39)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolveCompletely(EngineDiscoveryRequestResolution.java:103)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.run(EngineDiscoveryRequestResolution.java:83)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolver.resolve(EngineDiscoveryRequestResolver.java:113)
	at org.junit.jupiter.engine.discovery.DiscoverySelectorResolver.resolveSelectors(DiscoverySelectorResolver.java:46)
	at org.junit.jupiter.engine.JupiterTestEngine.discover(JupiterTestEngine.java:69)
	at org.junit.platform.launcher.core.EngineDiscoveryOrchestrator.discoverEngineRoot(EngineDiscoveryOrchestrator.java:152)
	... 13 more
Caused by: java.lang.ClassCircularityError: java/lang/WeakPairMap$Pair$Weak
	at java.base/java.lang.WeakPairMap$Pair.weak(WeakPairMap.java:201)
	at java.base/java.lang.WeakPairMap.putIfAbsent(WeakPairMap.java:123)
	at java.base/java.lang.Module.implAddReads(Module.java:488)
	at java.base/java.lang.Module.implAddReads(Module.java:449)
	at java.base/java.lang.System$2.addReads(System.java:2335)
	at java.base/jdk.internal.module.Modules.addReads(Modules.java:90)
	at java.base/java.lang.reflect.Proxy$ProxyBuilder.lambda$getDynamicModule$1(Proxy.java:918)
	at java.base/jdk.internal.loader.AbstractClassLoaderValue$Memoizer.get(AbstractClassLoaderValue.java:329)
	at java.base/jdk.internal.loader.AbstractClassLoaderValue.computeIfAbsent(AbstractClassLoaderValue.java:205)
	at java.base/java.lang.reflect.Proxy$ProxyBuilder.getDynamicModule(Proxy.java:908)
	at java.base/java.lang.reflect.Proxy$ProxyBuilder.mapToModule(Proxy.java:846)
	at java.base/java.lang.reflect.Proxy$ProxyBuilder.<init>(Proxy.java:651)
	at java.base/java.lang.reflect.Proxy$ProxyBuilder.<init>(Proxy.java:656)
	at java.base/java.lang.reflect.Proxy.lambda$getProxyConstructor$0(Proxy.java:429)
	at java.base/jdk.internal.loader.AbstractClassLoaderValue$Memoizer.get(AbstractClassLoaderValue.java:329)
	at java.base/jdk.internal.loader.AbstractClassLoaderValue.computeIfAbsent(AbstractClassLoaderValue.java:205)
	at java.base/java.lang.reflect.Proxy.getProxyConstructor(Proxy.java:427)
	at java.base/java.lang.reflect.Proxy.newProxyInstance(Proxy.java:1037)
	at java.base/sun.reflect.annotation.AnnotationParser$1.run(AnnotationParser.java:302)
	at java.base/sun.reflect.annotation.AnnotationParser$1.run(AnnotationParser.java:300)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:318)
	at java.base/sun.reflect.annotation.AnnotationParser.annotationForMap(AnnotationParser.java:300)
	at java.base/sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:289)
	at java.base/sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:121)
	at java.base/sun.reflect.annotation.AnnotationParser.parseSelectAnnotations(AnnotationParser.java:102)
	at java.base/sun.reflect.annotation.AnnotationType.<init>(AnnotationType.java:146)
	at java.base/sun.reflect.annotation.AnnotationType.getInstance(AnnotationType.java:85)
	at java.base/sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:262)
	at java.base/sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:121)
	at java.base/sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:73)
	at java.base/java.lang.Class.createAnnotationData(Class.java:4068)
	at java.base/java.lang.Class.annotationData(Class.java:4057)
	at java.base/java.lang.Class.getAnnotation(Class.java:3940)
	at java.base/java.lang.reflect.AnnotatedElement.isAnnotationPresent(AnnotatedElement.java:292)
	at java.base/java.lang.Class.isAnnotationPresent(Class.java:3950)
	at org.junit.platform.commons.util.AnnotationUtils.findAnnotation(AnnotationUtils.java:136)
	at org.junit.platform.commons.util.AnnotationUtils.isAnnotated(AnnotationUtils.java:105)
	at org.junit.jupiter.engine.discovery.predicates.IsTestableMethod.test(IsTestableMethod.java:52)
	at org.junit.jupiter.engine.discovery.predicates.IsTestMethod.test(IsTestMethod.java:23)
	at org.junit.jupiter.engine.discovery.predicates.IsTestableMethod.test(IsTestableMethod.java:26)
	at java.base/java.util.function.Predicate.lambda$or$2(Predicate.java:101)
	at java.base/java.util.function.Predicate.lambda$or$2(Predicate.java:101)
	at org.junit.platform.commons.util.ReflectionUtils.findMethod(ReflectionUtils.java:1368)
	at org.junit.platform.commons.util.ReflectionUtils.isMethodPresent(ReflectionUtils.java:1267)
	at org.junit.jupiter.engine.discovery.predicates.IsTestClassWithTests.hasTestOrTestFactoryOrTestTemplateMethods(IsTestClassWithTests.java:50)
	at org.junit.jupiter.engine.discovery.predicates.IsTestClassWithTests.test(IsTestClassWithTests.java:46)
	at org.junit.jupiter.engine.discovery.predicates.IsTestClassWithTests.test(IsTestClassWithTests.java:27)
	at java.base/java.util.function.Predicate.lambda$or$2(Predicate.java:101)
	at org.junit.jupiter.engine.discovery.MethodSelectorResolver.resolve(MethodSelectorResolver.java:87)
	at org.junit.jupiter.engine.discovery.MethodSelectorResolver.resolve(MethodSelectorResolver.java:75)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.lambda$resolve$2(EngineDiscoveryRequestResolution.java:150)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1602)
	at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
	at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:150)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
	at java.base/java.util.stream.ReferencePipeline.findFirst(ReferencePipeline.java:647)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:189)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolve(EngineDiscoveryRequestResolution.java:126)
	at org.junit.platform.engine.support.discovery.EngineDiscoveryRequestResolution.resolveCompletely(EngineDiscoveryRequestResolution.java:92)BENJAMIN J HESS
01/24/2023, 12:00 AMThibaut Bodart
01/25/2023, 9:23 AMarrayContaining .
I need this logic for an array that is not defined as a value of an object property.  Instead, the array is returned as the body of the response.
[
  {....},
  {....}
]
Ideally, I would need a newJsonArrayContaining method in LambdaDsl. See an example below.
return logAndReturn(builder.given("multiple connections exists")
				.uponReceiving("request to get all connections")
				.method("GET")
				.path("/connections")
				.headers(headers())
				.willRespondWith()
				.status(200)
				.headers(headers())
				.body(newJsonArrayContaining(arr -> {
					......
					});
				}).build()));
As I understand it, there is currently no way to use arrayContaining in this situation. Is my understanding correct?Thibaut Bodart
01/25/2023, 11:06 PM4.3.17 to 4.4.4 since I would like to use the V4 Pact specifications.
My response is in JSON format and only contains a UUID.  See below a valid JSON response.
"08f7a210-95db-4827-bcc8-d2025ba506cf"
I am using the following code to define the interaction:
...
.willRespondWith()
.status(201)
.headers(headers())
.body(PactDslJsonRootValue.uuid(JOB_ID)));
With 4.3.17,  using a Pact v3 contract, the generated contract looks like:
"response": {
        "body": "\"08f7a210-95db-4827-bcc8-d2025ba506cf\"",
        .....
}
With 4.4.4, using a Pact v4 contract, it looks like:
"response": {
        "body": {
          "content": "08f7a210-95db-4827-bcc8-d2025ba506cf",
          "contentType": "application/json",
          "encoded": false
        },
.....
}
The content value is not a valid JSON value in the case of 4.4.4.  For this reason, the contract cannot be verified by the provider (also using pact-jvm 4.4.4). See the exception below.  This is expected since "08f7a210-95db-4827-bcc8-d2025ba506cf" is not a valid JSON document whereas "\"08f7a210-95db-4827-bcc8-d2025ba506cf\"" is.
1.1) Invalid JSON (1:5), found unexpected character '7'
Am I doing something wrong? If I modify the contract manually as illustrated below, the provider can successfully verify it. Is there a way to generate the response below using the Pact DSL? 
"response": {
  "body": {
    "content": "\"08f7a210-95db-4827-bcc8-d2025ba506cf\"",
    "contentType": "application/json",
    "encoded": false
  },
Thanks in advance!Ivan Mikhalka
01/27/2023, 5:10 AM4.1.39 , using Pactflow as a pact broker. There is a several consumers for same provider, and I can run verification for all consumers using similar config:
fromPactBroker {
   withSelectors {
      selector('tagConsumer1', true, null, 'Consumer1')
      selector('tagConsumer2', true, null, 'Consumer2')
   }
}
via command
`./gradlew pactVerify -Ppact.verifier.publishResults=true -Dpact.provider.branch=git branch --show-current -Dpact.provider.tag=`git branch --show-current``
How can I run verification for only one specified consumer?Kevin de Boer
01/30/2023, 1:48 PM@Test
@PactTestFor(providerName = "provider1", port = "1234")
public void example(MockServer provider1mock) {
    ...
}
However, when I do this in a multiprovider test:
@Test
@PactTestFor(pactMethods = {"createProvider1Pact", "createProvider2Pact"}, port = "1234")
public void example(@ForProvider("provider1") MockServer provider1mock, @ForProvider("provider2") MockServer provider2mock) {
   ...
}
I get an “address already in used” exception. Which is logical since I instantiate 2 instances of mockserver, and only provide 1 port. It tries to launch both on the same port.
However I have found no way of specifying which mockserver should use which port. Is there a way to do this?
I could not find anything in the documentation or source code, though I am unfamiliar with kotlin, I may have missed something. I tried making a subclass of MockServer and set the port myself, but then I ran into injection/instantiation issues with my new class.
Alternatively, i have also not found a way to let the application use whatever random port is chosen for the mock.Onur
01/31/2023, 6:13 AMChimein
01/31/2023, 11:51 AMSebastian Suarez
01/31/2023, 6:25 PMUlises Cervino
02/01/2023, 10:33 AMID it checks that the ID of the returned entity matchesUlises Cervino
02/01/2023, 10:34 AMUlises Cervino
02/01/2023, 10:34 AMUlises Cervino
02/01/2023, 10:34 AMGitHub
02/02/2023, 10:26 PMPavithra Navaneeth
02/03/2023, 3:17 AMUlises Cervino
02/03/2023, 2:16 PMvalueFromProviderState in responses? I'm struggling to figure out how this work. The test I have in mind is a consumer saying "when I GET /entity/1 I expect a response like {id: 1}" for instance, where 1 in the path matches the 1 in the response (I already have pathFromProviderState working fine)Ulises Cervino
02/03/2023, 2:17 PMbody.valueFromProviderState(
                                                                "basketId",
                                                                "basketId",
                                                                existingBasketId.toString())Ulises Cervino
02/03/2023, 2:17 PM"matchingRules": {
          "body": {
            "$.basketId": {
              "combine": "AND",
              "matchers": [
                {
                  "match": "type"
                }
              ]
            },Ulises Cervino
02/03/2023, 2:17 PM1.1) body: $.basketId Expected "698c7e00-1e27-436e-a2e6-f7dd94ea98a7" to be nullUlises Cervino
02/03/2023, 2:18 PMMap liveBasketExists(Map _ignored_params) {
        Map<String, Object> state = new HashMap<>();
        InternalBasket internalBasket =
                repository.createBasket(TestSupport.Repository.basketWithDefaults()).orElseThrow();
        // the key in this state-map corresponds to the variable in the expression in the consumer
        // test, i.e. in the
        // example consumer test we have a call like .pathFromProviderState("/${basketId}", ...)
        state.put("basketId", internalBasket.getBasketId());
        return state;
    }Sebastian Suarez
02/03/2023, 7:26 PMpackage consumer.pact.springboot;
import org.junit.jupiter.api.extension.ExtendWith;
import au.com.dius.pact.consumer.MockServer;
import au.com.dius.pact.core.model.RequestResponsePact;
import au.com.dius.pact.core.model.annotations.Pact;
import au.com.dius.pact.consumer.dsl.PactDslJsonBody;
import au.com.dius.pact.consumer.dsl.PactDslWithProvider;
import au.com.dius.pact.consumer.junit5.PactConsumerTestExt;
import au.com.dius.pact.consumer.junit5.PactTestFor;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import static org.hamcrest.MatcherAssert.assertThat;
import static <http://org.hamcrest.Matchers.is|org.hamcrest.Matchers.is>;
@ExtendWith(PactConsumerTestExt.class)
@PactTestFor(providerName = "provider-springboot")
class UserPactTest {
    @Pact(consumer="consumer-springboot")
    public RequestResponsePact getUser(PactDslWithProvider builder) {
        PactDslJsonBody body = new PactDslJsonBody();
        body.stringType("id", "1");
        body.stringType("name", "Sebastian Suarez");
        body.stringType("email", "<mailto:sebastian@email.com|sebastian@email.com>");
        body.stringType("phone", "3145289654");
        body.stringType("password", "xhzASfe&1");
        return builder
                .given("a user with ID 1 exists")
                .uponReceiving("a request to get a user")
                .path("/api/v1/users/1")
                .method("GET")
                .headers(headers())
                .willRespondWith()
                .status(200)
                .body(body)
                .toPact();
    }
    @Test
    @PactTestFor(pactMethod = "getUser")
    void testGetProduct(MockServer mockServer) throws IOException {
        UserData user = new UserRequest().setUrl(mockServer.getUrl()).getUser(1);
        assertThat(user.getName(), is("Sebastian Suarez"));
    }
    private Map<String, String> headers() {
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/json; charset=utf-8");
        return headers;
    }
}
package consumer.pact.springboot;
import org.apache.http.client.fluent.Request;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.List;
public class UserRequest {
    private String url;
    public UserRequest setUrl(String url) {
        this.url = url;
        return this;
    }
    public UserData getUser(int id) throws IOException {
        return Request.Get(this.url + "/api/v1/users/" + id)
                .addHeader("Accept", "application/json")
                .execute().handleResponse(httpResponse -> {
                    try {
                        ObjectMapper mapper = new ObjectMapper();
                        return mapper.readValue(httpResponse.getEntity().getContent(), UserData.class);
                    } catch (JsonMappingException e) {
                        throw new IOException(e);
                    }
                });
    }
}Pavithra Navaneeth
02/06/2023, 12:42 AMItzhak Eretz Kdosha
02/06/2023, 12:16 PMBasu Silviu
02/06/2023, 12:38 PMscheme, host, port are deprecated, but the documentation doesn't explicitly say what replaced them. I do see a url, Can any of you please confirm if url replaces the other 3?Basu Silviu
02/06/2023, 12:38 PMÉdouard Lopez
02/06/2023, 4:10 PMjava.lang.IllegalArgumentException: Invalid pact broker host specified ('${pactbroker.host:}'). Please provide a valid host or specify the system property 'pactbroker.host'.
with the command
./gradlew testContract \
 -Ppact.verifier.publishResults=true \
 -Ppactbroker.url="<http://foo.bar>" \
 --infoUlises Cervino
02/06/2023, 7:16 PMUlises Cervino
02/06/2023, 7:17 PM<http://miningmadness.com|miningmadness.com>