Skip to content

Commit

Permalink
feat(JUnit 4): Allow provider state generator to fall back to the pro…
Browse files Browse the repository at this point in the history
…vider state parameters
  • Loading branch information
rholshausen committed Jul 11, 2024
1 parent 7550a6d commit e586656
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,8 @@ open class InteractionRunner(
return if (interaction.providerStates.isNotEmpty()) {
var stateChange = statement
for (state in interaction.providerStates.reversed()) {
testContext.putAll(state.params.filterValues { it != null } as Map<String, Any>)

val methods = findStateChangeMethod(state, testTarget.getStateHandlers())
if (methods.isEmpty()) {
return if (ignoreMissingStateChangeMethod()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@ import au.com.dius.pact.provider.TestResultAccumulator
import au.com.dius.pact.provider.VerificationReporter
import au.com.dius.pact.provider.VerificationResult
import au.com.dius.pact.provider.junit.target.HttpTarget
import au.com.dius.pact.provider.junitsupport.State
import au.com.dius.pact.provider.junitsupport.target.Target
import au.com.dius.pact.provider.junitsupport.target.TestTarget
import junit.framework.AssertionFailedError
import org.apache.commons.lang3.tuple.Pair
import org.jetbrains.annotations.NotNull
import org.junit.runner.notification.RunNotifier
import org.junit.runners.model.Statement
import org.junit.runners.model.TestClass
import spock.lang.Specification
import spock.util.environment.RestoreSystemProperties
Expand Down Expand Up @@ -459,4 +461,61 @@ class InteractionRunnerSpec extends Specification {
1 * notifier.fireTestIgnored({ it.displayName.startsWith('consumer - Upon Interaction 2 ') })
0 * _
}

@SuppressWarnings('PublicInstanceField')
static class StateChangeClazz {
@TestTarget
public final Target target = new MockTarget()

@State('state 1')
Map<String, Object> state1() {
[a: 100, b: '200']
}
}

def 'withStateChanges copies any returned values to the test context'() {
given:
def interaction1 = new RequestResponseInteraction('Interaction 1', [ new ProviderState('state 1') ])
def pact = new RequestResponsePact(new Provider(), new Consumer(), [ interaction1 ])
def statement = [evaluate: { }] as Statement
def verifier = [:] as IProviderVerifier
def testTarget = [
getStateHandlers: { [] },
getVerifier: { verifier }
] as Target
def stateChangeClazz = new TestClass(StateChangeClazz)

def runner = new InteractionRunner(stateChangeClazz, pact, UnknownPactSource.INSTANCE)

when:
def stateChangeStatement = runner.withStateChanges(interaction1, new StateChangeClazz(), statement, testTarget)
stateChangeStatement.evaluate()

then:
runner.testContext == [a: 100, b: '200']
}

def 'withStateChanges falls back to provider state parameters'() {
given:
def interaction1 = new RequestResponseInteraction('Interaction 1', [
new ProviderState('state 1', [b: 200, c: 'test'])
])
def pact = new RequestResponsePact(new Provider(), new Consumer(), [ interaction1 ])
def statement = [evaluate: { }] as Statement
def verifier = [:] as IProviderVerifier
def testTarget = [
getStateHandlers: { [] },
getVerifier: { verifier }
] as Target
def stateChangeClazz = new TestClass(StateChangeClazz)

def runner = new InteractionRunner(stateChangeClazz, pact, UnknownPactSource.INSTANCE)

when:
def stateChangeStatement = runner.withStateChanges(interaction1, new StateChangeClazz(), statement, testTarget)
stateChangeStatement.evaluate()

then:
runner.testContext == [a: 100, b: '200', c: 'test']
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package au.com.dius.pact.provider.junit;

import au.com.dius.pact.provider.junit.target.HttpTarget;
import au.com.dius.pact.provider.junitsupport.Provider;
import au.com.dius.pact.provider.junitsupport.State;
import au.com.dius.pact.provider.junitsupport.loader.PactFolder;
import au.com.dius.pact.provider.junitsupport.target.Target;
import au.com.dius.pact.provider.junitsupport.target.TestTarget;
import com.github.restdriver.clientdriver.ClientDriverRule;
import org.junit.Before;
import org.junit.ClassRule;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Collections;
import java.util.Map;

import static com.github.restdriver.clientdriver.RestClientDriver.giveResponse;
import static com.github.restdriver.clientdriver.RestClientDriver.onRequestTo;

@Provider("ProviderStateParametersInjected")
@PactFolder("pacts")
@RunWith(PactRunner.class)
public class ProviderStateParametersInjectedTest {
private static final Logger LOGGER = LoggerFactory.getLogger(ProviderStateParametersInjectedTest.class);

@ClassRule
public static final ClientDriverRule embeddedService = new ClientDriverRule(9241);

@TestTarget
public final Target target = new HttpTarget(9241);

@Before
public void before() {
embeddedService.addExpectation(
onRequestTo("/api/hello/John"),
giveResponse("{\"name\": \"John\"}", "application/json")
);
}

@State("User exists")
public Map<String, Object> defaultState(Map<String, Object> params) {
LOGGER.debug("Provider state params = " + params);
return Collections.emptyMap();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"consumer": {
"name": "SomeConsumer"
},
"interactions": [
{
"description": "Hello John",
"providerStates": [
{
"name": "User exists",
"params": {
"name": "John"
}
}
],
"request": {
"generators": {
"path": {
"dataType": "STRING",
"expression": "/api/hello/${name}",
"type": "ProviderState"
}
},
"method": "GET",
"path": "/api/hello/James"
},
"response": {
"body": {
"name": "John"
},
"headers": {
"Content-Type": "application/json"
},
"status": 200
}
}
],
"metadata": {
"pact-jvm": {
"version": "4.6.7"
},
"pactSpecification": {
"version": "3.0.0"
}
},
"provider": {
"name": "ProviderStateParametersInjected"
}
}
2 changes: 1 addition & 1 deletion provider/junit5/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ The library is available on maven central using:

* group-id = `au.com.dius.pact.provider`
* artifact-id = `junit5`
* version-id = `4.3.x`
* version-id = `4.6.x`

## Overview

Expand Down

0 comments on commit e586656

Please sign in to comment.