pact-foundation / pact-jvm

JVM version of Pact. Enables consumer driven contract testing, providing a mock service and DSL for the consumer project, and interaction playback and verification for the service provider project.
https://docs.pact.io
Apache License 2.0
1.09k stars 480 forks source link

Check JSON Body contains key objects and key arrays #500

Open sureshmaruthirao opened 7 years ago

sureshmaruthirao commented 7 years ago

Hi, I am just exploring PACT_JVM to validate incoming JSON file against certain rules. Sample Incoming JSON is below:

{ "customerOrderNumber": "DNUPTD01171429617", "createdDate": 1500335319208, "submittedDate": 1500335319208, "orderType": "CREATE", "orderStatus": { "status": "RECEIVED", "subStatus": "RECEIVED" }, "productGroups": { "group": [{ "id": "GROUP_01", "name": "SHIRTS_01", "type": "MENS", "sequence": 1, "price": [{ "amount": 8.75, "currencyType": "USD", "priceType": "DueToday", "taxDetail": { "amount": 0.0 }, "total": 8.75 }, { "amount": 0.0, "currencyType": "USD", "total": 0.0 }, { "amount": 0.0, "currencyType": "USD", "total": 0.0 }, { "amount": 0.0, "currencyType": "USD", "priceType": "DUENOW", "total": 0.0 }], "promotionReferences": { "promotionReference": ["PROMOTION_1"] }, "characteristics": { "losgCharacteristics": { "losgReferenceId": "losg315710616", "sequence": 1, "losgType": "ACC", "productCategory": "ONLINE", "primaryIndicator": false, "dealerCode": "Z0066", "market": "TNK", "subMarket": "415", "serviceArea": "006772002695", "priceCode": "415", "accountReference": "ACCOUNT_01", "wLOSCharacteristics": { "billingSystemId": "T" }, "fulfillmentMethod": "DF", "shippingDetailReference": "SHIPPING_INFO_01" } } }] }, "lineItems": { "lineItem": [{ "id": "111817034145", "sequence": 1, "productCode": "prod8720378", "productSKU": "4797G", "billingCode": "4797G", "productType": "HARDGOOD", "displayName": "U S POLA - V NECK T-SHIRT", "systemName": "CAS SPK PRESIDIO MARGE CLR", "action": "ADD", "price": { "amount": 159.0, "msrp": 159.0, "priceType": "DueToday", "taxDetail": { "preCalculatedTax": { "taxableCost": 126.0, "taxableMSRP": 159.0, "taxableUnitPrice": 159.0, "orderTaxAreaId": 390950000, "shipFromTaxAreaId": 431570560, "shipToTaxAreaId": 180091237 }, "lineItemTaxes": [{ "taxLineId": 1, "taxCode": "SALESTAX", "memo": "SALESTAX", "printName": "Sales Tax", "taxable": "N", "skuSpecific": "false", "jurisdictionLevel": "Sales Tax", "jurisdictionName": "Sales Tax", "taxAmount": 9.54, "taxRate": 0.06, "taxDate": "2017-06-05" }] }, "total": 168.54 }, "locationId": "K006", "payments": { "payment": [{ "paymentOptionReference": "PAYMENT_OPTION_01" }] }, "quantity": 1, "promotionReferences": { "promotionReference": ["PROMOTION_1"] }, "groupReferences": { "groupReference": ["GROUP_01"] }, "characteristics": { "wirelessLineItemCharacteristics": { "nciEligibleIndicator": false } }, "hardGood": { "hardGoodType": "ACCESSORY" } }, { "id": "88878ShippingFee", "sequence": 2, "productCode": "NOT_AVAILABLE", "productSKU": "88878", "billingCode": "88878", "productType": "MISC_CHARGE", "displayName": "ShippingFee", "systemName": "SHIPPING_FEE", "price": { "amount": 0.0, "priceType": "DueToday", "taxDetail": { "preCalculatedTax": { "taxableCost": 0.0, "taxableMSRP": 14.95, "taxableUnitPrice": 0.0, "orderTaxAreaId": 390950000, "shipFromTaxAreaId": 431570560, "shipToTaxAreaId": 180091237 }, "lineItemTaxes": [{ "taxLineId": 2, "taxCode": "SALESTAX", "memo": "SALESTAX", "printName": "Sales Tax", "taxable": "N", "skuSpecific": "false", "jurisdictionLevel": "Sales Tax", "jurisdictionName": "Sales Tax", "taxAmount": 0.0, "taxRate": 0.0, "taxDate": "2017-06-05" }] }, "total": 14.95 }, "payments": { "payment": [{ "paymentOptionReference": "PAYMENT_OPTION_01" }] }, "quantity": 1, "groupReferences": { "groupReference": ["GROUP_01"] } }] }, "names": { "name": [{ "id": "NAME_01", "firstName": "ABC", "lastName": "QWE", "emailAddress": "XXXXXXXX@GMAIL.COM", "primaryContactPhones": [{ "phoneNumber": "1111108029", "contactPhoneType": "HOME_PHONE" }, { "phoneNumber": "1111111111", "contactPhoneType": "WORK_PHONE" }] }] }, "addresses": { "address": [{ "id": "ADDRESS_01", "unparsedAddress": { "addressLine1": "1000 W SPRINGA VLLY Dr", "city": "CAVE CITY", "state": "KY", "zip": "75001", "country": "US" }, "additionalDetails": { "additionalDetail": [{ "code": "ValidatedAddress", "value": "true" }] } }, { "id": "ADDRESS_02", "unparsedAddress": { "addressLine1": "1000 W SPRINGA VLLY Dr", "city": "CAVE CITY", "state": "KY", "zip": "75001", "country": "US" }, "additionalDetails": { "additionalDetail": [{ "code": "ValidatedAddress", "value": "true" }] } }, { "id": "ADDRESS_03", "unparsedAddress": { "addressLine1": "1000 W SPRINGA VLLY Dr", "city": "CAVE CITY", "state": "KY", "zip": "75001", "country": "US" }, "additionalDetails": { "additionalDetail": [{ "code": "ValidatedAddress", "value": "true" }] } }, { "id": "ADDRESS_04", "unparsedAddress": { "addressLine1": "1000 W SPRINGA VLLY Dr", "addressLine2": "", "city": "CHICAGO", "state": "IL", "zip": "75001", "county": "COOK", "country": "US" }, "parsedAddress": { "addressStreetLine": "350 N ORLEANS ST STE 1270", "houseNumber": "350", "streetName": "ORLEANS", "streetType": "ST", "city": "CHICAGO", "state": "IL", "zip": "75001", "zipCodeExtension": "2148", "county": "COOK", "country": "COOK" }, "additionalDetails": { "additionalDetail": [{ "code": "ValidatedAddress", "value": "true" }] } }] }, "accounts": { "account": [{ "id": "ACCOUNT_01", "sequence": 1, "accountCategory": "MOBILITY_ACCOUNT", "accountSubCategory": "NEW", "paymentArrangement": "PAYPAL", "billingAccountNumber": "992863227376", "billingDetail": [{ "nameReference": "NAME_01", "addressReference": "ADDRESS_03", "authentication": { "dob": "DQS~-Lr-=.", "driversLicense": {

                },
                "ssn": "5RFV6VEAH"
            },
            "codingAccuracySupportSystemAddress": {
                "addressLines": ["LEISA SUMMERS",
                "805 GREENVIEW DR",
                "CAVE CITY KY 42127"]
            },
            "previousAddress": "N"
        }],
        "creditCheck": {
            "creditCheckRanIndicator": false
        },
        "liabilityType": "INDIVIDUAL",
        "accountType": "INDIVIDUAL",
        "accountSubType": "R",
        "enterpriseType": "IRU",
        "b2bReference": "B2B_01",
        "langId": "ENGLISH",
        "market": "TNK",
        "subMarket": "415",
        "spokenLanguagePreference": "ENGLISH"
    }]
},
"paymentOptions": {
    "paymentOption": [{
        "id": "PAYMENT_OPTION_01",
        "sequence": 1,
        "capmConfig": {
            "merchantId": "ORDERGWCon",
            "sourceSystem": "HARDROCK",
            "sourceLocation": "CS",
            "sourceUser": "HARDROCK"
        },
        "paymentMethod": {
            "capm": {
                "preAuthDetail": {
                    "authorizationCode": "OL_DF170605780979",
                    "authorizationDate": "2017-06-05",
                    "authorizationExpirationDate": "2017-07-03",
                    "addressVerificationSystemCode": "NA",
                    "authorizationKey": "41870086"
                },
                "profileName": "ABC Bank",
                "profileOwnerId": "12343597664",
                "totalAmount": 183.48999999999998,
                "creditCardLast4Digits": "9999",
                "zipCode": "75001",
                "creditCardType": "VISA",
                "paymentProfileAction": "C_ORDER",
                "giftCardIndicator": false,
                "saveProfileIndicator": false
            }
        }
    }]
},
"promotions": {
    "promotion": [{
        "id": "PROMOTION_1",
        "promotionId": "promo4660036",
        "displayLevel": "ORDER",
        "sequence": 1,
        "promotionName": "It Pays to Stay in the Know! You are using a coupon code to get a free accessory (up to $50 value).",
        "amount": 26.25,
        "percent": 0.0,
        "fixedAmount": 0.0,
        "duration": 0,
        "promotionType": "PROMOTION",
        "effectiveInDays": 0,
        "complexDiscountIndicator": false
    }]
},
"shippingDetails": {
    "shippingDetail": [{
        "id": "SHIPPING_INFO_01",
        "sequence": 1,
        "nameReference": "NAME_01",
        "addressReference": "ADDRESS_01",
        "shippingCode": "AA0",
        "shippingPriceCode": "88888",
        "shippingMethod": "Priority",
        "carrierPreference": "unknown"
    }]
},
"b2bs": {
    "b2b": [{
        "id": "B2B_01",
        "b2bContractProvider": "WMARTWS",
        "b2bContractType": "NONCB",
        "b2bFAN": "00085683",
        "b2bSkipUpgradeEligibilityIndicator": false,
        "b2bIgnoreDepositRequiredIndicator": false,
        "b2bFANBusinessName": "WPP Group"
    }]
},
"totalPrice": {
    "price": [{
        "amount": 8.75,
        "currencyType": "USD",
        "priceType": "DueToday",
        "taxDetail": {
            "amount": 0.0
        },
        "total": 8.75
    },
    {
        "amount": 0.0,
        "currencyType": "USD",
        "priceType": "RC",
        "total": 0.0
    },
    {
        "amount": 0.0,
        "currencyType": "USD",
        "priceType": "NRC",
        "total": 0.0
    },
    {
        "amount": 0.0,
        "currencyType": "USD",
        "priceType": "DUENOW",
        "total": 0.0
    }]
},
"creditPolicy": {
    "crsmOnFlag": false
},
"agentCode": "Z0066",
"agentLocation": "Z0066",
"affiliateId": "AysPbYF8vuM-.AT.~2323",
"affiliateReferalDate": 1500323568000,
"termsAndConditions": {
    "termsAndConditionAccepted": [{
        "id": "TC_01",
        "agreementType": "TOS",
        "agreementText": "By providing this information, you certify that you are the card owner or have authorization to charge on this card.",
        "accepted": "Y",
        "timestamp": 1496665952091,
        "version": "0"
    }]
},
"orderContact": {
    "nameReference": "NAME_01",
    "primaryEmailAddress": "kkkkk@yahoo.com"
},
"orderSource": {
    "locale": "en_US",
    "clientType": "DESKTOP",
    "channel": "DE-M",
    "application": "WMARTWS",
    "browserId": "A001275652439",
    "additionalDetails": {
        "additionalDetail": [{
            "code": "SENDER",
            "value": "CCC"
        }]
    }
},
"encryptedIndicator": true,
"commonOrderIndicator": true,
"summaryCreatedIndicator": false,
"falloutHistory": {
    "fallouts": [{
        "falloutAPI": "CALCULATETAX",
        "falloutCode": "DATA_ERROR",
        "falloutDescription": "DATA_ERROR:96e39999-2bad-4a81-8148-86f2fd3e3395"
    }]
}

}

In the above JSON falloutHistory is optional and it comes only if there any validation error while checking on the other system.

Using my plain blank mind after reading - I have to just check only the key elements present or not like below I specified the DslPart

DslPart body = new PactDslJsonBody() .stringType("customerOrderNumber") .stringType("orderType") .object("productGroups") .eachKeyMappedToAnArrayLike("group") .stringType("id") .eachKeyMappedToAnArrayLike("price") //.closeArray() .closeObject() .eachLike("lineItems") .eachKeyMappedToAnArrayLike("lineItem") .numberType("quantity") .object("price") .object("taxDetail") .closeObject() .closeObject() .closeArray() .object("payments") .eachKeyMappedToAnArrayLike("payment") .closeArray() .closeObject()
.object("promotionReferences") .closeObject() .object("characteristics") .closeObject() .closeObject() .object("names") .eachKeyMappedToAnArrayLike("name") .eachKeyMappedToAnArrayLike("primaryContactPhones") .closeArray() .closeArray() .closeObject() .object("addresses") .eachKeyMappedToAnArrayLike("address") .closeArray() .closeObject() .object("accounts") .eachKeyMappedToAnArrayLike("account") .eachKeyMappedToAnArrayLike("billingDetail") .closeArray() .closeArray()
.closeObject() .object("paymentOptions") .eachKeyMappedToAnArrayLike("paymentOption") .closeArray() .closeObject() .object("promotions") .eachKeyMappedToAnArrayLike("promotion") .closeArray() .closeObject() .object("shippingDetails") .eachKeyMappedToAnArrayLike("shippingDetail") .closeArray() .closeObject() .object("b2bs") .eachKeyMappedToAnArrayLike("b2b") .closeArray() .closeObject() .object("totalPrice") .eachKeyMappedToAnArrayLike("price") .closeArray() .closeObject() .object("termsAndConditions") .eachKeyMappedToAnArrayLike("termsAndConditionAccepted") .closeArray() .closeObject() .object("orderSource") .stringType("clientType") .closeObject() ;

Basically I am checking objects within the JSON with available in array and some key elements When i write it for first object I got the below JSON pact, when I started adding other object check it is giving me error. Generated PACT JSON and error below: PACT JSON

{ "provider": { "name": "product-provider-demo" }, "consumer": { "name": "product-consumer-demo" }, "interactions": [ { "description": "ConsumerDemoTest interaction", "request": { "method": "GET", "path": "/product" }, "response": { "status": 200, "headers": { "Content-Type": "application/json;charset=UTF-8" }, "body": { "customerOrderNumber": "BFxFcnuvlTtXcjPmeIuf", "orderType": "rbLluporifHQkAbkGbmo", "productGroups": { "group": [ { "id": "TJtIEnClGyZRgPCZRoUX", "price": [ {

                                }
                            ]
                        }
                    ]
                }
            },
            "matchingRules": {
                "$.body.*[*].*": {
                    "min": 0,
                    "match": "type"
                },
                "$.body.*": {
                    "min": 0,
                    "match": "type"
                },
                "$.body.orderType": {
                    "match": "type"
                },
                "$.body.*[*].id": {
                    "match": "type"
                },
                "$.body.customerOrderNumber": {
                    "match": "type"
                }
            }
        },
        "providerState": "test demo first state"
    }
],
"metadata": {
    "pact-specification": {
        "version": "2.0.0"
    },
    "pact-jvm": {
        "version": "3.3.3"
    }
}

}

Error: java.lang.UnsupportedOperationException: use the eachLike() form at au.com.dius.pact.consumer.dsl.PactDslJsonArray.eachLike(PactDslJsonArray.java:68) at product_demo.ConsumerDemoTest3.createFragment(ConsumerDemoTest3.java:59) at au.com.dius.pact.consumer.ConsumerPactTest.testPact(ConsumerPactTest.java:22) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)


I tried various ways of defining and closing but not able to find the correct or easier way to check.

ConsumerDemoTest3.txt

sureshmaruthirao commented 7 years ago

Tried with below one DslPart body = new PactDslJsonBody() .stringType("customerOrderNumber") .object("productGroups") .eachKeyMappedToAnArrayLike("group") .stringType("id") .object("characteristics") .closeObject() .object("lineItems") .eachKeyMappedToAnArrayLike("lineItem") .object("price")

              .closeObject()
              .object("names")
                    .eachKeyMappedToAnArrayLike("name")
                        .stringType("id")
                    .closeArray()
              .closeObject()

Still error

java.lang.UnsupportedOperationException: can't call closeArray on an Object at au.com.dius.pact.consumer.dsl.PactDslJsonBody.closeArray(PactDslJsonBody.java:537) at product_demo.ConsumerDemoTest3.createFragment(ConsumerDemoTest3.java:65) at au.com.dius.pact.consumer.ConsumerPactTest.testPact(ConsumerPactTest.java:22) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

uglyog commented 7 years ago

I think the problem is that eachKeyMappedToAnArrayLike first creates an array and then creates an object to be the example. So you need to first close the example object then the array

.eachKeyMappedToAnArrayLike("name")
    .stringType("id")
    .closeObject) // This is probably missing
.closeArray()
sureshmaruthirao commented 7 years ago

Thanks for the reply. I implemented that and when I am trying to build the i am getting below error java.lang.IllegalArgumentException: requirement failed: The following merge conflicts occurred: Cannot merge pacts as there were 1 conflicts between the interactions at scala.Predef$.require(Predef.scala:224) at au.com.dius.pact.consumer.PactGenerator.writeAllToFile(PactGenerator.scala:71) at au.com.dius.pact.consumer.ConsumerPactRunner$$anonfun$writeIfMatching$2.apply(ConsumerPactRunner.scala:16) at au.com.dius.pact.consumer.ConsumerPactRunner$$anonfun$writeIfMatching$2.apply(ConsumerPactRunner.scala:15) at scala.util.Success.foreach(Try.scala:236) at scala.util.Try$WithFilter.foreach(Try.scala:140) at au.com.dius.pact.consumer.ConsumerPactRunner$.writeIfMatching(ConsumerPactRunner.scala:15) at au.com.dius.pact.consumer.ConsumerPactRunner$.writeIfMatching(ConsumerPactRunner.scala:12) at au.com.dius.pact.consumer.ConsumerPactRunner$$anonfun$runAndWritePact$2.apply(ConsumerPactRunner.scala:38) at au.com.dius.pact.consumer.ConsumerPactRunner$$anonfun$runAndWritePact$2.apply(ConsumerPactRunner.scala:38) at scala.Option.fold(Option.scala:158) at au.com.dius.pact.consumer.ConsumerPactRunner.runAndWritePact(ConsumerPactRunner.scala:38) at au.com.dius.pact.model.PactFragment.duringConsumerSpec(PactFragment.scala:13) at au.com.dius.pact.model.PactFragment.runConsumer(PactFragment.scala:21) at au.com.dius.pact.consumer.ConsumerPactTest.testPact(ConsumerPactTest.java:25) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:114) at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:57) at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:66) at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32) at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93) at com.sun.proxy.$Proxy2.processTestClass(Unknown Source) at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:109) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:147) at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:129) at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404) at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63) at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:46) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)

sureshmaruthirao commented 7 years ago

The consumerTest2 code is below one

`package product_demo;

import static junit.framework.TestCase.assertEquals; import static org.junit.Assert.assertNotNull;

import java.io.File; import java.io.IOException; import java.io.StringWriter; import java.net.URI; import java.util.HashMap; import java.util.Map;

import org.json.JSONObject;

import com.fasterxml.jackson.databind.ObjectMapper;

import au.com.dius.pact.consumer.ConsumerPactTest; import au.com.dius.pact.consumer.dsl.PactDslJsonBody; import au.com.dius.pact.consumer.dsl.PactDslWithProvider; import au.com.dius.pact.model.PactFragment;

/**

PactDslJsonBody dslbody = new PactDslJsonBody();

    dslbody
    .stringMatcher("customerOrderNumber","\\w*","A123BBB233232_01BA")
    .stringMatcher("orderType","\\w*", "CREATE")
    .decimalType("createdDate", Double.valueOf("4545454545444"))
    .decimalType("submittedDate", Double.valueOf("4545454545444"))
    .booleanType("encryptedIndicator", false)
    .booleanType("commonOrderIndicator", false)
    .booleanType("summaryCreatedIndicator", false)
    .stringMatcher("agentCode","\\w*", "AGENTK35K6I")
    .stringMatcher("agentLocation","[a-zA-Z0-9\\@\\#\\$\\%\\&\\*\\(\\)\\-\\_\\+\\]\\[\\'\\;\\:\\?\\.\\,\\!\\^]+$", "K3KDFDFA#3333")
    .stringMatcher("affiliateId","[a-zA-Z0-9\\@\\#\\$\\%\\&\\*\\(\\)\\-\\_\\+\\]\\[\\'\\;\\:\\?\\.\\,\\!\\^]+$", "AysPbYF8v.-ATTym9QM.-_11223")
    .decimalType("affiliateReferalDate", Double.valueOf("999999999999"))
    .object("orderStatus")
        .stringMatcher("status","\\w*",  "CREATE")
        .stringMatcher("subStatus","\\w*",  "RECEIVED")
    .closeObject()
    .object("productGroups")
        .eachKeyMappedToAnArrayLike("group")
                .stringType("id")
                .eachKeyMappedToAnArrayLike("price")
                    .decimalType("amount",199.999)
                    .closeObject()
                .closeArray()
            .closeObject()
        .closeArray()
    .closeObject()
    .object("lineItems")
    .eachKeyMappedToAnArrayLike("lineItem")
            .stringType("id")
            .eachKeyMappedToAnArrayLike("price")
                    .decimalType("amount",19999.99)
                .closeObject()
            .closeArray()
        .closeObject()
    .closeArray()
.closeObject()

.object("names")
    .eachKeyMappedToAnArrayLike("name")
            .stringType("id")
        .closeObject()
    .closeArray()
.closeObject()
.object("addresses")
        .eachKeyMappedToAnArrayLike("address")
                .stringType("id")
            .closeObject()
        .closeArray()
.closeObject()
    .object("accounts")
    .eachKeyMappedToAnArrayLike("account")
        .stringType("id")
        .closeObject()
    .closeArray()
.closeObject()

    .object("paymentOptions")
        .eachKeyMappedToAnArrayLike("paymentOption")
                .stringType("id")
            .closeObject()

        .closeArray()
    .closeObject()

    .object("promotions")
        .eachKeyMappedToAnArrayLike("promotion")
            .stringType("id")
            .closeObject()
        .closeArray()
    .closeObject()
    .object("shippingDetails")
        .eachKeyMappedToAnArrayLike("shippingDetail")
            .stringType("id")
            .closeObject()
        .closeArray()
    .closeObject()
    .object("b2bs")
        .eachKeyMappedToAnArrayLike("b2b")
            .stringType("id")
            .closeObject()
        .closeArray()
    .closeObject()
    .object("totalPrice")
        .eachKeyMappedToAnArrayLike("price")
                .decimalType("amount",19999.99)
            .closeObject()
        .closeArray()
    .closeObject()
    .object("creditPolicy")
        .booleanType("crsmOnFlag")
    .closeObject()
    .object("termsAndConditions")
        .eachKeyMappedToAnArrayLike("termsAndConditionAccepted")
            .stringType("id")
            .closeObject()
        .closeArray()
    .closeObject()
    .object("orderContact")
        .stringType("nameReference")
        .stringType("primaryEmailAddress")
    .closeObject()
    .object("orderSource")
        .stringType("channel")

    .closeObject()
    .object("falloutHistory")
        .eachLike("fallouts")
    .closeObject()
    ;

    System.out.println(jobj.toString());
    Map<String, String> headers = new HashMap<>();
    headers.put("Content-Type", "application/json;charset=UTF-8");
    return pactDslWithProvider
            .given("test demo first state")
            .uponReceiving("ConsumerDemoTest interaction")
                .path("/product")
                //.query("customerOrderNumber=null")
                .method("GET")
            .willRespondWith()
                .status(200)
                .headers(headers)
                .body(dslbody)
            .toFragment();
     //@formatter:on
}

protected String providerName() {
    return "product-provider-demo";
}

protected String consumerName() {
    return "product-consumer-demo";
}

protected void runTest(String url) throws IOException {
    URI productInfoUri = URI.create(String.format("%s/%s", url, "product"));
    ProductRestFetcher productRestFetcher = new ProductRestFetcher();
    String product = productRestFetcher.fetchProductInfo(productInfoUri);

    assertNotNull(product);

}

} `

uglyog commented 7 years ago

Just clean out your old pacts and try running it again.

sureshmaruthirao commented 7 years ago

Thanks. Clean that now pact is getting generated. It will be helpful how can check PACT verification result through Java code only. Using spring boot web UI with the controller and simple AJAX post method. I developed UI to give the inputJSON and mapping it Map using Jackson object mapper. Now I want to validate the inputJSON with pact file specification and display back the result. The end objective is to generate multiple PACT files, chose the PACT file mapped to key display in the combo box. Get inputJSON and validated it and verify with PACT file. pact_project

sureshmaruthirao commented 7 years ago

Tried ConsumerInfo consumer = new ConsumerInfo(); //file based broker approach - instead of cloud pact broker consumer.setName("Foo_Consumer"); consumer.setPactFile(new File("C:/Suresh/microservices-pact-mvn-master/microservices-pact-maven-master/microservices-pact-consumer/target/pacts/Foo_Consumer-Foo_Provider.json")); Pact testConsumerPact = (Pact) new PactReader().loadPact(consumer.getPactFile()); It is giving error at the point of in
Pact testConsumerPact = (Pact) new PactReader().loadPact(consumer.getPactFile()); import groovyx.net.http.RESTClient in PactReader class image

uglyog commented 7 years ago

You need to provide the stack trace of the exception, which will indicate what the cause is.

sureshmaruthirao commented 7 years ago

Please see the stack trace for the code ` //assume the consumer and provider both are self ConsumerInfo consumer = new ConsumerInfo(); //file based broker approach - instead of cloud pact broker - set the consumer as per PACT file consumer.setName("Foo_Consumer"); //read the pact file consumer.setPactFile(new File("C:/Suresh/att/microservices-pact-mvn-master/microservices-pact-maven-master/microservices-pact-consumer/target/pacts/Foo_Consumer-Foo_Provider.json")); Pact testConsumerPact = (Pact) new PactReader().loadPact(consumer.getPactFile()); //assume the provider is self ProviderClient client = new ProviderClient(); //only one interaction is there
List interactions = testConsumerPact.getInteractions(); Interaction interaction1 = interactions.get(0); Map<?,?> clientResponse = null; ObjectMapper objectMapper = new ObjectMapper(); Response res = new Response(); res.setStatus((int)clientResponse.get("statusCode")); try { //map the input json from UI to Map clientResponse = objectMapper.readValue(search.getInputjson(), Map.class); } catch (IOException e) { // TODO Auto-generated catch block result.setMsg(e.getMessage()); e.printStackTrace(); return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(result);

    }

//compare the Map - use pact instead of traditional diff - need to check any other logic Map<String, Object> validationresult = (Map<String, Object>) ResponseComparison.compareResponse(res, clientResponse, (int) clientResponse.get("status"), (Map) clientResponse.get("headers"), (String) clientResponse.get("data")); `

10:10:02,254 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.groovy] 10:10:02,254 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback-test.xml] 10:10:02,254 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Found resource [logback.xml] at [file:/C:/Suresh/att/microservices-pact-mvn-master/microservices-pact_ui_client/microservices-pact_ui_client/target/classes/logback.xml] 10:10:02,383 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - debug attribute not set 10:10:02,386 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - About to instantiate appender of type [ch.qos.logback.core.ConsoleAppender] 10:10:02,394 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [STDOUT] 10:10:02,454 |-WARN in ch.qos.logback.core.ConsoleAppender[STDOUT] - This appender no longer admits a layout as a sub-component, set an encoder instead. 10:10:02,454 |-WARN in ch.qos.logback.core.ConsoleAppender[STDOUT] - To ensure compatibility, wrapping your layout in LayoutWrappingEncoder. 10:10:02,454 |-WARN in ch.qos.logback.core.ConsoleAppender[STDOUT] - See also http://logback.qos.ch/codes.html#layoutInsteadOfEncoder for details 10:10:02,456 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [org.springframework.web] to ERROR 10:10:02,456 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting additivity of logger [org.springframework.web] to false 10:10:02,456 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[org.springframework.web] 10:10:02,456 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting level of logger [com.mkyong] to DEBUG 10:10:02,456 |-INFO in ch.qos.logback.classic.joran.action.LoggerAction - Setting additivity of logger [com.mkyong] to false 10:10:02,456 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[com.mkyong] 10:10:02,457 |-INFO in ch.qos.logback.classic.joran.action.RootLoggerAction - Setting level of ROOT logger to ERROR 10:10:02,457 |-INFO in ch.qos.logback.core.joran.action.AppenderRefAction - Attaching appender named [STDOUT] to Logger[ROOT] 10:10:02,457 |-INFO in ch.qos.logback.classic.joran.action.ConfigurationAction - End of configuration. 10:10:02,458 |-INFO in ch.qos.logback.classic.joran.JoranConfigurator@6f195bc3 - Registering current configuration as safe fallback point

. _ _ /\ / '_ () \ \ \ \ ( ( )\ | ' | '| | ' \/ ` | \ \ \ \ \/ _)| |)| | | | | || (| | ) ) ) ) ' |__| .|| ||| |\, | / / / / =========|_|==============|__/=//// :: Spring Boot :: (v1.5.4.RELEASE)

2017-08-21 10:12:47 ERROR o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: groovy/json/JsonSlurper] with root cause java.lang.ClassNotFoundException: groovy.json.JsonSlurper at java.net.URLClassLoader.findClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source) at java.lang.ClassLoader.loadClass(Unknown Source) at au.com.dius.pact.model.PactReader.loadFile(PactReader.groovy:157) at org.codehaus.groovy.vmplugin.v7.IndyInterface.selectMethod(IndyInterface.java:232) at au.com.dius.pact.model.PactReader.loadPact(PactReader.groovy:26) at au.com.dius.pact.model.PactReader.loadPact(PactReader.groovy) at com.oce.controller.SearchController.getValidationResultViaAjax(SearchController.java:96) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133) at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) at javax.servlet.http.HttpServlet.service(HttpServlet.java:661) at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) at javax.servlet.http.HttpServlet.service(HttpServlet.java:742) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:105) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:80) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:799) at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Unknown Source)

uglyog commented 7 years ago

java.lang.ClassNotFoundException: groovy.json.JsonSlurper means you are missing the Groovy JAR as a dependency.

sureshmaruthirao commented 7 years ago

Groovy JAR is available in dependencies. Please see the attached POM file and below image.


image

pom.txt

uglyog commented 7 years ago

It may be displayed in your IDE, but it is not available when your spring boot app is running. You need to check the classpath that the app is running with.

doinglivingtest commented 7 years ago

Im getting an error in .eachKeyMappedToAnArrayLike() method, IDE says "Cannot resolve method 'eachKeyMappedToAnArrayLike(java.lang.String)'"

public static DslPart getPactBodyFormulaEvaluation() { PactDslJsonBody responseBody = new PactDslJsonBody() .stringMatcher("formulas","\w*","floorPrice") .eachKeyMappedToAnArrayLike("lines"); // error is generated in this line

    return responseBody;
}

Do you know if this method is deprecated or some idea why can't I use it?

Help!!

uglyog commented 7 years ago

@doinglivingtest Check you have the pact-jvm versions 3.3.3 or later (3.5.7 is the latest current version)

habhilash commented 6 years ago

Can someone please tell me how to match more than one object inside an array. For instance, below is the code :

PactDslJsonArray.arrayEachLike()
  .array("attributes")
                    .object()
                        .stringValue("type", "A")
                        .stringValue("name", "legacy")
                        .stringMatcher("stringValue", "\\d{1}", "7")
                        .numberValue("doubleValue", null)
                        .numberValue("longValue", null)
                        .booleanValue("booleanValue", null)
                    .closeObject()
                    .object()
                        .stringValue("type", "B")
                        .stringValue("name", "supreme")
                        .stringValue("stringValue", "OnPremise")
                        .numberValue("doubleValue", null)
                        .numberValue("longValue", null)
                        .booleanValue("booleanValue", null)
                    .closeObject()
                    .object()
                        .stringValue("type", "java.lang.String")
                        .stringValue("name", "description")
                        .stringMatcher("stringValue", "[a-zA-Z0-9]*", "")
                        .numberValue("doubleValue", null)
                        .numberValue("longValue", null)
                        .booleanValue("booleanValue", null)
                    .closeObject()
 .closeArray()
 .closeObject();

Now, my response may contain the objects shown above in random order. How do I verify the objects generically?

uglyog commented 6 years ago

@habhilash in theory you need to use the eachLike functions that assure that each item in the list matches the example objects, and then use the or matcher. But I have a suspicion this might not work across objects. You'll have to test it.

But looking at your example, the three objects are identical in structure, it's just the stringValue regular expressions that differ. So you could just have an or with the three different regex matchers for that field.

habhilash commented 6 years ago

Hi @uglyog ,

I tried using eachLike() function and got the follwoing error. Below is the snippet and error :

PactDslJsonArray.arrayEachLike()
  .eachLike("attributes")
                    .object()
                        .stringValue("type", "A")
                        .stringValue("name", "legacy")
                        .stringMatcher("stringValue", "\\d{1}", "7")
                        .numberValue("doubleValue", null)
                        .numberValue("longValue", null)
                        .booleanValue("booleanValue", null)
                    .closeObject()
    .closeArray()
 .closeObject();
objc[12828]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/bin/java (0x10ad424c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x10cdc04e0). One of the two will be used. Which one is undefined.
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

java.lang.RuntimeException: Failed to invoke pact method

    at au.com.dius.pact.consumer.BaseProviderRule.getPacts(BaseProviderRule.java:193)
    at au.com.dius.pact.consumer.BaseProviderRule$1.evaluate(BaseProviderRule.java:66)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at au.com.dius.pact.consumer.BaseProviderRule.getPacts(BaseProviderRule.java:190)
    ... 16 more
Caused by: java.lang.UnsupportedOperationException: use the object(String name) form
    at au.com.dius.pact.consumer.dsl.PactDslJsonBody.object(PactDslJsonBody.java:520)
    at consumer.EntitySearchContractTestsEachKey.entitySearchPact1(EntitySearchContractTestsEachKey.java:59)
    ... 21 more

So, I don't think the object is supported here. Could you point me to an example to use 'or'

uglyog commented 6 years ago

You don't need the .object() method call after the eachLike, it does it for you automatically.

habhilash commented 6 years ago

@uglyog, I have multiple objects to be verified as shown below. eachLike() creates array and object. But, how to add multiple objects to eachLike() ? So, could you please suggest me how to use EachLike for the below example :

PactDslJsonArray.arrayEachLike()
  .array("attributes")
                    .object()
                        .stringValue("type", "A")
                        .stringValue("name", "legacy")
                        .stringMatcher("stringValue", "\\d{1}", "7")
                        .numberValue("doubleValue", null)
                        .numberValue("longValue", null)
                        .booleanValue("booleanValue", null)
                    .closeObject()
                    .object()
                        .stringValue("type", "B")
                        .stringValue("name", "supreme")
                        .stringValue("stringValue", "OnPremise")
                        .numberValue("doubleValue", null)
                        .numberValue("longValue", null)
                        .booleanValue("booleanValue", null)
                    .closeObject()
                    .object()
                        .stringValue("type", "java.lang.String")
                        .stringValue("name", "description")
                        .stringMatcher("stringValue", "[a-zA-Z0-9]*", "")
                        .numberValue("doubleValue", null)
                        .numberValue("longValue", null)
                        .booleanValue("booleanValue", null)
                    .closeObject()
 .closeArray()
 .closeObject();
uglyog commented 6 years ago

From what I can see, your multiple objects are all the same. They have the same structure, so you could use one definition for all of them.

sureshmaruthirao commented 6 years ago

Dynamic objects and Arrays with same structure never going to be the same.

uglyog commented 6 years ago

@sureshmaruthirao Pact is for testing structure, so for Pact things with the same structure will always be the same.

habhilash commented 6 years ago

@uglyog : I am trying to test the structure only using PACT. But I am testing the structure of value as well using Regular Expressions. And regular expression will differ for each and every object. In that case, verification of structure for each object should be supported. Also, the order of objects should not matter and currently, PACT looks for the order of objects as well. How can we verify all the objects without order? Also, you mentioned about OR operator. Can you please explain how to use OR operator and how to verify the structure of objects without order when I dont use eachLike() ?.