From 49f4d908e5c46a15eeae84f85fa04f8aa55b6235 Mon Sep 17 00:00:00 2001 From: Ronald Holshausen Date: Wed, 15 Feb 2023 16:29:06 +1100 Subject: [PATCH 1/5] feat: Support modifying the request metadata in the provider test before being sent to the plugin --- provider/junit5/build.gradle | 2 + .../junit5/PactVerificationExtension.kt | 14 +- .../pact/provider/junit5/PluginTestTarget.kt | 3 +- .../PactVerificationExtensionSpec.groovy | 197 +++++++++++------- .../dius/pact/provider/ProviderVerifier.kt | 2 +- .../pact/provider/RequestDataToBeVerified.kt | 38 ++++ 6 files changed, 180 insertions(+), 76 deletions(-) create mode 100644 provider/src/main/kotlin/au/com/dius/pact/provider/RequestDataToBeVerified.kt diff --git a/provider/junit5/build.gradle b/provider/junit5/build.gradle index 9a97c9d30..ad770b625 100644 --- a/provider/junit5/build.gradle +++ b/provider/junit5/build.gradle @@ -28,4 +28,6 @@ dependencies { exclude group: 'org.yaml' } testImplementation 'org.yaml:snakeyaml:1.33' + testImplementation 'org.mockito:mockito-core:2.28.2' + testImplementation 'org.mockito:mockito-inline:2.28.2' } diff --git a/provider/junit5/src/main/kotlin/au/com/dius/pact/provider/junit5/PactVerificationExtension.kt b/provider/junit5/src/main/kotlin/au/com/dius/pact/provider/junit5/PactVerificationExtension.kt index 8ec58081e..a666320a1 100644 --- a/provider/junit5/src/main/kotlin/au/com/dius/pact/provider/junit5/PactVerificationExtension.kt +++ b/provider/junit5/src/main/kotlin/au/com/dius/pact/provider/junit5/PactVerificationExtension.kt @@ -14,9 +14,12 @@ import au.com.dius.pact.provider.DefaultTestResultAccumulator import au.com.dius.pact.provider.IProviderVerifier import au.com.dius.pact.provider.ProviderInfo import au.com.dius.pact.provider.ProviderVerifier +import au.com.dius.pact.provider.RequestData +import au.com.dius.pact.provider.RequestDataToBeVerified import au.com.dius.pact.provider.TestResultAccumulator import au.com.dius.pact.provider.junitsupport.VerificationReports import au.com.dius.pact.provider.reporters.ReporterManager +import io.pact.plugins.jvm.core.InteractionVerificationData import mu.KLogging import org.apache.hc.core5.http.ClassicHttpRequest import org.apache.hc.core5.http.HttpRequest @@ -74,9 +77,10 @@ open class PactVerificationExtension( return when (parameterContext.parameter.type) { Pact::class.java -> true Interaction::class.java -> true - ClassicHttpRequest::class.java, HttpRequest::class.java -> testContext.target is HttpTestTarget || testContext.target is HttpsTestTarget + ClassicHttpRequest::class.java, HttpRequest::class.java -> testContext.target is HttpTestTarget PactVerificationContext::class.java -> true ProviderVerifier::class.java -> true + RequestData::class.java -> testContext.target is PluginTestTarget else -> false } } @@ -89,6 +93,14 @@ open class PactVerificationExtension( ClassicHttpRequest::class.java, HttpRequest::class.java -> store.get("httpRequest") PactVerificationContext::class.java -> store.get("interactionContext") ProviderVerifier::class.java -> store.get("verifier") + RequestData::class.java -> { + val request = store.get("request") + if (request is RequestDataToBeVerified) { + request + } else { + null + } + } else -> null } } diff --git a/provider/junit5/src/main/kotlin/au/com/dius/pact/provider/junit5/PluginTestTarget.kt b/provider/junit5/src/main/kotlin/au/com/dius/pact/provider/junit5/PluginTestTarget.kt index caaa06431..5c823e83b 100644 --- a/provider/junit5/src/main/kotlin/au/com/dius/pact/provider/junit5/PluginTestTarget.kt +++ b/provider/junit5/src/main/kotlin/au/com/dius/pact/provider/junit5/PluginTestTarget.kt @@ -10,6 +10,7 @@ import au.com.dius.pact.provider.IProviderInfo import au.com.dius.pact.provider.IProviderVerifier import au.com.dius.pact.provider.PactVerification import au.com.dius.pact.provider.ProviderResponse +import au.com.dius.pact.provider.RequestDataToBeVerified import io.pact.plugins.jvm.core.CatalogueEntry import io.pact.plugins.jvm.core.CatalogueManager import io.pact.plugins.jvm.core.DefaultPluginManager @@ -87,7 +88,7 @@ class PluginTestTarget(private val config: MutableMap = mutableMap return when (val v4pact = pact.asV4Pact()) { is Ok -> when (val result = DefaultPluginManager.prepareValidationForInteraction(transportEntry, v4pact.value, interaction.asV4Interaction(), config)) { - is Ok -> result.value to transportEntry + is Ok -> RequestDataToBeVerified(result.value) to transportEntry is Err -> throw RuntimeException("Failed to configure the interaction for verification - ${result.error}") } is Err -> throw RuntimeException("PluginTestTarget can only be used with V4 Pacts") diff --git a/provider/junit5/src/test/groovy/au/com/dius/pact/provider/junit5/PactVerificationExtensionSpec.groovy b/provider/junit5/src/test/groovy/au/com/dius/pact/provider/junit5/PactVerificationExtensionSpec.groovy index 5f81940f0..646709c61 100644 --- a/provider/junit5/src/test/groovy/au/com/dius/pact/provider/junit5/PactVerificationExtensionSpec.groovy +++ b/provider/junit5/src/test/groovy/au/com/dius/pact/provider/junit5/PactVerificationExtensionSpec.groovy @@ -2,6 +2,9 @@ package au.com.dius.pact.provider.junit5 import au.com.dius.pact.core.model.Consumer import au.com.dius.pact.core.model.FilteredPact +import au.com.dius.pact.core.model.Interaction +import au.com.dius.pact.core.model.OptionalBody +import au.com.dius.pact.core.model.Pact import au.com.dius.pact.core.model.PactBrokerSource import au.com.dius.pact.core.model.Provider import au.com.dius.pact.core.model.Request @@ -13,39 +16,79 @@ import au.com.dius.pact.core.support.expressions.ValueResolver import au.com.dius.pact.provider.IConsumerInfo import au.com.dius.pact.provider.IProviderInfo import au.com.dius.pact.provider.IProviderVerifier +import au.com.dius.pact.provider.ProviderVerifier +import au.com.dius.pact.provider.RequestData +import au.com.dius.pact.provider.RequestDataToBeVerified import au.com.dius.pact.provider.TestResultAccumulator +import org.apache.hc.core5.http.ClassicHttpRequest +import org.apache.hc.core5.http.HttpRequest import org.junit.jupiter.api.extension.ExtensionContext +import org.junit.jupiter.api.extension.ParameterContext import spock.lang.Issue +import spock.lang.Shared import spock.lang.Specification -class PactVerificationExtensionSpec extends Specification { +import java.lang.reflect.Parameter - def 'updateTestResult uses the original pact when pact is filtered '() { - given: - PactVerificationContext context - ExtensionContext.Store store = Stub { +import static org.mockito.Mockito.mock +import static org.mockito.Mockito.when + +@SuppressWarnings('UnnecessaryGetter') +class PactVerificationExtensionSpec extends Specification { + @Shared PactVerificationContext context + PactVerificationExtension extension + @Shared ExtensionContext.Store store + @Shared ExtensionContext extContext + @Shared Map contextMap + ValueResolver mockValueResolver + @Shared RequestResponseInteraction interaction1, interaction2 + @Shared RequestResponsePact pact + PactBrokerSource pactSource + @Shared ClassicHttpRequest classicHttpRequest + @Shared ProviderVerifier verifier + @Shared RequestDataToBeVerified data + + def setupSpec() { + verifier = Mock(ProviderVerifier) + store = Stub { get(_) >> { args -> if (args[0] == 'interactionContext') { context + } else { + contextMap[args[0]] } } + put(_, _) >> { args -> contextMap[args[0]] = args[1] } } - ExtensionContext extContext = Stub { + + extContext = Stub { getStore(_) >> store } - def mockValueResolver = Mock(ValueResolver) + interaction1 = new RequestResponseInteraction('interaction1', [], new Request(), new Response()) + interaction2 = new RequestResponseInteraction('interaction2', [], new Request(), new Response()) + pact = new RequestResponsePact(new Provider(), new Consumer(), [interaction1, interaction2]) + classicHttpRequest = Mock(ClassicHttpRequest) + context = new PactVerificationContext(store, extContext, Stub(TestTarget), Stub(IProviderVerifier), + Stub(ValueResolver), Stub(IProviderInfo), Stub(IConsumerInfo), interaction1, pact, []) + data = new RequestDataToBeVerified(OptionalBody.empty(), [:]) + } + + def setup() { + mockValueResolver = Mock(ValueResolver) + pactSource = new PactBrokerSource('localhost', '80', 'http') + contextMap = [ + httpRequest: classicHttpRequest, + verifier: verifier + ] + } - def interaction1 = new RequestResponseInteraction('interaction1', [], new Request(), new Response()) - def interaction2 = new RequestResponseInteraction('interaction2', [], new Request(), new Response()) - def pact = new RequestResponsePact(new Provider(), new Consumer(), [interaction1, interaction2]) + def 'updateTestResult uses the original pact when pact is filtered '() { + given: def filteredPact = new FilteredPact(pact, { it.description == 'interaction1' }) PactBrokerSource pactSource = new PactBrokerSource('localhost', '80', 'http') - context = new PactVerificationContext(store, extContext, Stub(TestTarget), Stub(IProviderVerifier), - Stub(ValueResolver), Stub(IProviderInfo), Stub(IConsumerInfo), interaction1, pact, []) - - PactVerificationExtension extension = new PactVerificationExtension(filteredPact, pactSource, interaction1, - 'service', 'consumer', mockValueResolver) + extension = new PactVerificationExtension(filteredPact, pactSource, interaction1, 'service', 'consumer', + mockValueResolver) extension.testResultAccumulator = Mock(TestResultAccumulator) when: @@ -58,28 +101,7 @@ class PactVerificationExtensionSpec extends Specification { def 'updateTestResult uses the pact itself when pact is not filtered '() { given: - PactVerificationContext context - ExtensionContext.Store store = Stub { - get(_) >> { args -> - if (args[0] == 'interactionContext') { - context - } - } - } - ExtensionContext extContext = Stub { - getStore(_) >> store - } - def mockValueResolver = Mock(ValueResolver) - - def interaction1 = new RequestResponseInteraction('interaction1', [], new Request(), new Response()) - def interaction2 = new RequestResponseInteraction('interaction2', [], new Request(), new Response()) - def pact = new RequestResponsePact(new Provider(), new Consumer(), [interaction1, interaction2]) - PactBrokerSource pactSource = new PactBrokerSource('localhost', '80', 'http') - - context = new PactVerificationContext(store, extContext, Stub(TestTarget), Stub(IProviderVerifier), - Stub(ValueResolver), Stub(IProviderInfo), Stub(IConsumerInfo), interaction1, pact, []) - - PactVerificationExtension extension = new PactVerificationExtension(pact, pactSource, interaction1, + extension = new PactVerificationExtension(pact, pactSource, interaction1, 'service', 'consumer', mockValueResolver) extension.testResultAccumulator = Mock(TestResultAccumulator) @@ -92,28 +114,9 @@ class PactVerificationExtensionSpec extends Specification { def 'if updateTestResult fails, throw an exception'() { given: - PactVerificationContext context - ExtensionContext.Store store = Stub { - get(_) >> { args -> - if (args[0] == 'interactionContext') { - context - } - } - } - ExtensionContext extContext = Stub { - getStore(_) >> store - } - def mockValueResolver = Mock(ValueResolver) + pact = new RequestResponsePact(new Provider(), new Consumer(), [interaction1, interaction2], [:], pactSource) - def interaction1 = new RequestResponseInteraction('interaction1') - def interaction2 = new RequestResponseInteraction('interaction2') - PactBrokerSource pactSource = new PactBrokerSource('localhost', '80', 'http') - def pact = new RequestResponsePact(new Provider(), new Consumer(), [interaction1, interaction2 ], [:], pactSource) - - context = new PactVerificationContext(store, extContext, Stub(TestTarget), Stub(IProviderVerifier), - Stub(ValueResolver), Stub(IProviderInfo), Stub(IConsumerInfo), interaction1, pact, []) - - PactVerificationExtension extension = new PactVerificationExtension(pact, pactSource, interaction1, + extension = new PactVerificationExtension(pact, pactSource, interaction1, 'service', 'consumer', mockValueResolver) extension.testResultAccumulator = Mock(TestResultAccumulator) @@ -130,27 +133,75 @@ class PactVerificationExtensionSpec extends Specification { @Issue('#1572') def 'beforeEach method passes the property resolver on to the verification context'() { given: - def map = [:] - ExtensionContext.Store store = Stub { - get(_) >> { args -> map[args[0]] } - put(_, _) >> { args -> map[args[0]] = args[1] } - } - ExtensionContext extContext = Stub { - getStore(_) >> store - } - def mockValueResolver = Mock(ValueResolver) + pact = new RequestResponsePact(new Provider(), new Consumer(), [interaction1], [:], pactSource) - def interaction1 = new RequestResponseInteraction('interaction1') - PactBrokerSource pactSource = new PactBrokerSource('localhost', '80', 'http') - def pact = new RequestResponsePact(new Provider(), new Consumer(), [interaction1], [:], pactSource) - - PactVerificationExtension extension = new PactVerificationExtension(pact, pactSource, interaction1, + extension = new PactVerificationExtension(pact, pactSource, interaction1, 'service', 'consumer', mockValueResolver) when: extension.beforeEach(extContext) then: - map['interactionContext'].valueResolver == mockValueResolver + contextMap['interactionContext'].valueResolver == mockValueResolver + } + + def 'supports parameter test'() { + given: + context.target = target + extension = new PactVerificationExtension(pact, pactSource, interaction1, 'service', 'consumer', + mockValueResolver) + Parameter parameter = mock(Parameter) + when(parameter.getType()).thenReturn(parameterType) + ParameterContext parameterContext = Stub { + getParameter() >> parameter + } + + expect: + extension.supportsParameter(parameterContext, extContext) == result + + where: + + parameterType | target | result + Pact | new HttpTestTarget() | true + Interaction | new HttpTestTarget() | true + ClassicHttpRequest | new HttpTestTarget() | true + ClassicHttpRequest | new HttpsTestTarget() | true + ClassicHttpRequest | new MessageTestTarget() | false + HttpRequest | new HttpTestTarget() | true + HttpRequest | new HttpsTestTarget() | true + HttpRequest | new MessageTestTarget() | false + PactVerificationContext | new HttpTestTarget() | true + ProviderVerifier | new HttpTestTarget() | true + String | new HttpTestTarget() | false + RequestData | new HttpTestTarget() | false + RequestData | new PluginTestTarget() | true + } + + def 'resolve parameter test'() { + given: + extension = new PactVerificationExtension(pact, pactSource, interaction1, 'service', 'consumer', + mockValueResolver) + Parameter parameter = mock(Parameter) + when(parameter.getType()).thenReturn(parameterType) + ParameterContext parameterContext = Stub { + getParameter() >> parameter + } + + contextMap['request'] = data + + expect: + extension.resolveParameter(parameterContext, extContext) == result + + where: + + parameterType | result + Pact | pact + Interaction | interaction1 + ClassicHttpRequest | classicHttpRequest + HttpRequest | classicHttpRequest + PactVerificationContext | context + ProviderVerifier | verifier + String | null + RequestData | data } } diff --git a/provider/src/main/kotlin/au/com/dius/pact/provider/ProviderVerifier.kt b/provider/src/main/kotlin/au/com/dius/pact/provider/ProviderVerifier.kt index f244c4f59..4265c046a 100644 --- a/provider/src/main/kotlin/au/com/dius/pact/provider/ProviderVerifier.kt +++ b/provider/src/main/kotlin/au/com/dius/pact/provider/ProviderVerifier.kt @@ -963,7 +963,7 @@ open class ProviderVerifier @JvmOverloads constructor ( logger.debug { "Verifying interaction => $request" } return when (val result = DefaultPluginManager.verifyInteraction( client as CatalogueEntry, - request as InteractionVerificationData, + (request as RequestDataToBeVerified).asInteractionVerificationData(), userConfig, pact, interaction diff --git a/provider/src/main/kotlin/au/com/dius/pact/provider/RequestDataToBeVerified.kt b/provider/src/main/kotlin/au/com/dius/pact/provider/RequestDataToBeVerified.kt new file mode 100644 index 000000000..81c3b9aae --- /dev/null +++ b/provider/src/main/kotlin/au/com/dius/pact/provider/RequestDataToBeVerified.kt @@ -0,0 +1,38 @@ +package au.com.dius.pact.provider + +import au.com.dius.pact.core.model.OptionalBody +import io.pact.plugins.jvm.core.InteractionVerificationData + +/** + * Request data that is going to be used by the plugin to create the request to be verified + */ +interface RequestData { + /** + * Data for the request of the interaction + */ + val requestData: OptionalBody + + /** + * Metadata associated with the request + */ + val metadata: Map +} + +/** + * Data used by a plugin to create a request to be verified + */ +data class RequestDataToBeVerified( + /** + * Data for the request of the interaction + */ + override val requestData: OptionalBody, + + /** + * Metadata associated with the request + */ + override val metadata: Map +): RequestData { + constructor(requestData: InteractionVerificationData) : this(requestData.requestData, requestData.metadata) + + fun asInteractionVerificationData() = InteractionVerificationData(requestData, metadata) +} From 461b9e348d9bfb1ac5fbda0afd3211553fee41cc Mon Sep 17 00:00:00 2001 From: Ronald Holshausen Date: Wed, 15 Feb 2023 16:32:48 +1100 Subject: [PATCH 2/5] feat: RequestData metadata needs to be a mutable Map --- .../au/com/dius/pact/provider/RequestDataToBeVerified.kt | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/provider/src/main/kotlin/au/com/dius/pact/provider/RequestDataToBeVerified.kt b/provider/src/main/kotlin/au/com/dius/pact/provider/RequestDataToBeVerified.kt index 81c3b9aae..6a01d07ac 100644 --- a/provider/src/main/kotlin/au/com/dius/pact/provider/RequestDataToBeVerified.kt +++ b/provider/src/main/kotlin/au/com/dius/pact/provider/RequestDataToBeVerified.kt @@ -15,7 +15,7 @@ interface RequestData { /** * Metadata associated with the request */ - val metadata: Map + val metadata: MutableMap } /** @@ -30,9 +30,11 @@ data class RequestDataToBeVerified( /** * Metadata associated with the request */ - override val metadata: Map + override val metadata: MutableMap ): RequestData { - constructor(requestData: InteractionVerificationData) : this(requestData.requestData, requestData.metadata) + constructor(requestData: InteractionVerificationData) : this( + requestData.requestData, requestData.metadata.toMutableMap() + ) fun asInteractionVerificationData() = InteractionVerificationData(requestData, metadata) } From 8f005cbd4a7e77df9238bd12a21b36c9493868df Mon Sep 17 00:00:00 2001 From: Ronald Holshausen Date: Wed, 15 Feb 2023 16:50:56 +1100 Subject: [PATCH 3/5] update changelog for release 4.4.6 --- CHANGELOG.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f1d699376..4df572720 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ To generate the log, run `git log --pretty='* %h - %s (%an, %ad)' TAGNAME..HEAD` replacing TAGNAME and HEAD as appropriate. +# 4.4.6 - Maintenance Release: Supports injecting request metadata from plugins into provider tests + +* 461b9e348 - feat: RequestData metadata needs to be a mutable Map (Ronald Holshausen, Wed Feb 15 16:32:48 2023 +1100) +* 49f4d908e - feat: Support modifying the request metadata in the provider test before being sent to the plugin (Ronald Holshausen, Wed Feb 15 16:29:06 2023 +1100) +* a43c2ea04 - chore: check for both cases when looking for pact do not track value (Ronald Holshausen, Tue Feb 14 12:42:52 2023 +1100) +* 21ada1b2e - fix: support metadata mismatches from results from plugins (Ronald Holshausen, Wed Feb 8 13:44:49 2023 +1100) +* 1bee97d14 - feat: add support for NotEmpty matcher in V4 DSL (Ronald Holshausen, Wed Feb 8 13:41:20 2023 +1100) +* 4ac9dcd0f - chore: Upgrade plugin driver to 0.3.1 (Ronald Holshausen, Wed Feb 8 13:40:07 2023 +1100) +* e71eb4d39 - feat: Upgrade plugin driver to 0.3.0 (supports message metadata) (Ronald Holshausen, Mon Feb 6 15:12:13 2023 +1100) +* 1a7ae6822 - bump version to 4.4.6 (Ronald Holshausen, Fri Feb 3 09:17:00 2023 +1100) + # 4.4.5 - Bugfix Release * 8c965dca6 - fix(regression): Changes for #1641 broke the use of plugin mock servers (Ronald Holshausen, Thu Feb 2 16:17:10 2023 +1100) From 0ca80c4b69f34e19836d72ecf9ce7d9a29e22312 Mon Sep 17 00:00:00 2001 From: Ronald Holshausen Date: Wed, 15 Feb 2023 17:01:23 +1100 Subject: [PATCH 4/5] bump version to 4.4.7 --- .../groovy/au.com.dius.pact.kotlin-common-conventions.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/buildSrc/src/main/groovy/au.com.dius.pact.kotlin-common-conventions.gradle b/buildSrc/src/main/groovy/au.com.dius.pact.kotlin-common-conventions.gradle index 9b58aa0a6..8773b759f 100644 --- a/buildSrc/src/main/groovy/au.com.dius.pact.kotlin-common-conventions.gradle +++ b/buildSrc/src/main/groovy/au.com.dius.pact.kotlin-common-conventions.gradle @@ -12,7 +12,7 @@ repositories { mavenCentral() } -version = '4.4.6' +version = '4.4.7' java { targetCompatibility = '11' From 8e125575f1abcf9b3452c8bc09e2d655a28bd70f Mon Sep 17 00:00:00 2001 From: Ronald Holshausen Date: Wed, 15 Feb 2023 17:02:12 +1100 Subject: [PATCH 5/5] chore: Update JUnit5 readme --- provider/junit5/README.md | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/provider/junit5/README.md b/provider/junit5/README.md index e7bbebab2..ab0e57293 100644 --- a/provider/junit5/README.md +++ b/provider/junit5/README.md @@ -40,7 +40,8 @@ For details on the provider and pact source annotations, refer to the [Pact juni You can set the test target (the object that defines the target of the test, which should point to your provider) on the `PactVerificationContext`, but you need to do this in a before test method (annotated with `@BeforeEach`). There are three -different test targets you can use: `HttpTestTarget`, `HttpsTestTarget` and `MessageTestTarget`. +main test targets you can use: `HttpTestTarget`, `HttpsTestTarget` and `MessageTestTarget`. There is also a `PluginTestTarget` +for use when the interactions are provided by a plugin. For example: @@ -201,7 +202,8 @@ or `setStateHandlers` methods. See [StateAnnotationsOnAdditionalClassTest](https Sometimes you may need to add things to the requests that can't be persisted in a pact file. Examples of these would be authentication tokens, which have a small life span. The Http and Https test targets support injecting the request that will executed into the test template method (of type `org.apache.http.HttpRequest` for versions 4.2.x and before, -`org.apache.hc.core5.http.HttpRequest` for versions 4.3.0+). +`org.apache.hc.core5.http.HttpRequest` for versions 4.3.0+), while the plugin test target supports injecting the data +that will be used to make the request into the test template method (as an instance of `au.com.dius.pact.provider.RequestData`). You can then add things to the request before calling the `verifyInteraction()` method. For example to add a header: @@ -218,16 +220,17 @@ For example to add a header: ## Objects that can be injected into the test methods -You can inject the following objects into your test methods (just like the `PactVerificationContext`). They will be null if injected before the -supported phase. +You can inject the following objects into your test methods (just like the `PactVerificationContext`). They will be +null if injected before the supported phase. -| Object | Can be injected from phase | Description | -| ------ | --------------- | ----------- | -| PactVerificationContext | @BeforeEach | The context to use to execute the interaction test | -| Pact | any | The Pact model for the test | -| Interaction | any | The Interaction model for the test | -| HttpRequest | @TestTemplate | The request that is going to be executed (only for HTTP and HTTPS targets) | -| ProviderVerifier | @TestTemplate | The verifier instance that is used to verify the interaction | +| Object | Can be injected from phase | Description | +|-------------------------|----------------------------|----------------------------------------------------------------------------| +| PactVerificationContext | @BeforeEach | The context to use to execute the interaction test | +| Pact | any | The Pact model for the test | +| Interaction | any | The Interaction model for the test | +| HttpRequest | @TestTemplate | The request that is going to be executed (only for HTTP and HTTPS targets) | +| RequestData | @TestTemplate | The request data that is going to be executed (only for the Plugin target) | +| ProviderVerifier | @TestTemplate | The verifier instance that is used to verify the interaction | ## Allowing the test to pass when no pacts are found to verify (version 4.0.7+) @@ -327,6 +330,9 @@ instructions for each plugin, but the default is to unpack the plugin into a sub (i.e., for the Protobuf plugin 0.0.0 it will be `protobuf-0.0.0`). The plugin manifest file must be present for the plugin to be able to be loaded. +Note that the request data used to generate the request for verification can be injected into the test template method +using the `au.com.dius.pact.provider.RequestData` type. This can be used to add any required metadata to the request. + # Test Analytics We are tracking anonymous analytics to gather important usage statistics like JVM version