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.08k stars 478 forks source link

"No signature of method" error in pact jvm 3.6.x #867

Open LoraV opened 5 years ago

LoraV commented 5 years ago

One of my coworkers wrote a couple provider-side Pact tests, got them working on her branch, and then merged from trunk to her branch in preparation for merging back to trunk. She started getting the following errors:

No signature of method: au.com.dius.pact.model.Response.generatedResponse() is applicable for argument typess: (java.util.Collections$SingletonMap) values: [[providerState:[:]]] Possible solutions: generatedResponse()

The version of Pact was 3.6.2. When I changed it to 3.5.24, the tests began passing. The tests broke with the same error in 3.6.1.

We're using the pact jvm fat jar. I don't think the version of Pact changed when she merged from trunk, and I'm pretty sure I've had provider tests pass with that version, so it may well be a dependency conflict based on other stuff added to the pom in that merge. However, nothing in the changeset for the pom file is standing out.

Here's the pact file, with a couple minor obfuscations:

{ "provider": { "name": "provider-ws" }, "consumer": { "name": "consumer-lib" }, "interactions": [ { "description": "a request for the template usage of components 20 and 588", "request": { "method": "GET", "path": "/usage/component-lookup", "query": { "componentIds": [ "20,588" ] } }, "response": { "status": 200, "headers": { "Content-Type": "application/json" }, "body": { "20": [], "588": [ { "name": "Test template name", "retired": null, "templateId": 123 }, { "name": "JSON Template Test", "retired": "2015-03-14", "templateId": 2718 } ] }, "matchingRules": { "header": { "Content-Type": { "matchers": [ { "match": "regex", "regex": "application/json" } ], "combine": "AND" } }, "body": { "$.588[0].templateId": { "matchers": [ { "match": "number" } ], "combine": "AND" }, "$.588[0].name": { "matchers": [ { "match": "type" } ], "combine": "AND" }, "$.588[1].templateId": { "matchers": [ { "match": "number" } ], "combine": "AND" }, "$.588[1].name": { "matchers": [ { "match": "type" } ], "combine": "AND" }, "$.588[1].retired": { "matchers": [ { "match": "date", "date": "yyyy-MM-dd" } ], "combine": "AND" } } } }, "providerStates": [ { "name": "component 20 is not used in templates, but component 588 is" } ] } ], "metadata": { "pactSpecification": { "version": "3.0.0" }, "pact-jvm": { "version": "3.5.24" } }, "createdAt": "2019-03-22T19:33:47+00:00" }

LoraV commented 5 years ago

It might also be the fact that this consumer pact was written with 3.5.24. If so, it would be nice if this project was backwards compatible from consumer to provider.

uglyog commented 5 years ago

The project follows semantic versioning. When a potential breaking change is made, the minor version is bumped (i.e. 3.5.x to 3.6.x).

Was the generatedResponse method being called in the test code? Because the signature of that method did change from 3.5.x to 3.6.0.

mikahjc commented 5 years ago

This issue came up with a different error, but on the same provider. From my testing, 3.6.1 works while 3.6.2+ doesn't. generatedResponse is not called in the test code, and we're not calling Companion.body either. The issue also goes away when we switch from the fat jar to only importing pact-jvm-provider-junit_2.12, so I'm wondering if there's some dependency issue that the fat jar is introducing.

The output/stack trace I'm getting is:

Verifying a pact between consumer-lib and provider-ws
  Given component 20 is not used in templates, but component 588 is
  a request for the template usage of components 20 and 588
java.lang.NoSuchMethodError: au.com.dius.pact.model.OptionalBody$Companion.body([B)Lau/com/dius/pact/model/OptionalBody;
        at au.com.dius.pact.provider.ResponseComparison$Companion.compareResponse(ResponseComparison.kt:130)
        at au.com.dius.pact.provider.ResponseComparison.compareResponse(ResponseComparison.kt)
        at au.com.dius.pact.provider.ProviderVerifier.verifyRequestResponsePact(ProviderVerifier.groovy:211)
        at au.com.dius.pact.provider.ProviderVerifier.verifyResponseFromProvider(ProviderVerifier.groovy:199)
        at au.com.dius.pact.provider.junit.target.HttpTarget.testInteraction(HttpTarget.kt:73)
        at au.com.dius.pact.provider.junit.InteractionRunner$interactionBlock$statement$1.evaluate(InteractionRunner.kt:208)
        at au.com.dius.pact.provider.junit.RunStateChanges.evaluate(RunStateChanges.kt:17)
        at au.com.dius.pact.provider.junit.InteractionRunner.run(InteractionRunner.kt:144)
        at au.com.dius.pact.provider.junit.PactRunner.runChild(PactRunner.kt:137)
        at au.com.dius.pact.provider.junit.PactRunner.runChild(PactRunner.kt:51)
        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.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
        at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
        at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
        at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:365)
        at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:273)
        at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238)
        at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:159)
        at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:384)
        at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:345)
        at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:126)
        at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:418)

The trace changes on 3.6.10 to:

java.lang.NoSuchMethodError: au.com.dius.pact.model.RequestResponseInteraction.getInteractionId()Ljava/lang/String;
        at au.com.dius.pact.provider.ProviderVerifierBase.verifyResponseFromProvider(ProviderVerifier.kt:509)
        at au.com.dius.pact.provider.junit.target.HttpTarget.testInteraction(HttpTarget.kt:73)
...