Skip to content

Commit 59c8740

Browse files
committed
Have multiple test cases be run by template
1 parent 4b44ae3 commit 59c8740

File tree

3 files changed

+92
-24
lines changed

3 files changed

+92
-24
lines changed

consumer/junit5/src/main/kotlin/au/com/dius/pact/consumer/junit5/AsynchronousMessageContext.kt

+3
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,7 @@ import org.junit.jupiter.api.extension.TestTemplateInvocationContext
66
class AsynchronousMessageContext(
77
val message: V4Interaction.AsynchronousMessage
88
): TestTemplateInvocationContext {
9+
override fun getDisplayName(invocationIndex: Int): String {
10+
return message.description
11+
}
912
}

consumer/junit5/src/main/kotlin/au/com/dius/pact/consumer/junit5/PactConsumerTestExt.kt

+27-24
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import au.com.dius.pact.core.support.expressions.DataType
3030
import au.com.dius.pact.core.support.expressions.ExpressionParser
3131
import au.com.dius.pact.core.support.isNotEmpty
3232
import io.github.oshai.kotlinlogging.KLogging
33+
import org.apache.hc.core5.util.ReflectionUtils
3334
import org.junit.jupiter.api.Disabled
3435
import org.junit.jupiter.api.Nested
3536
import org.junit.jupiter.api.TestTemplate
@@ -268,36 +269,38 @@ class PactConsumerTestExt : Extension, BeforeTestExecutionCallback, BeforeAllCal
268269
): BasePact {
269270
val store = context.getStore(NAMESPACE)
270271
val key = "pact:${providerInfo.providerName}"
272+
var methods = pactMethods
273+
if (methods.isEmpty()) {
274+
methods = AnnotationSupport.findAnnotatedMethods(context.requiredTestClass, Pact::class.java, HierarchyTraversalMode.TOP_DOWN)
275+
.map { m -> m.name}
276+
}
277+
271278
return when {
272279
store[key] != null -> store[key] as BasePact
273280
else -> {
274-
val pact = if (pactMethods.isEmpty()) {
275-
lookupPact(providerInfo, "", context)
276-
} else {
277-
val head = pactMethods.first()
278-
val tail = pactMethods.drop(1)
279-
val initial = lookupPact(providerInfo, head, context)
280-
tail.fold(initial) { acc, method ->
281-
val pact = lookupPact(providerInfo, method, context)
282-
283-
if (pact.provider != acc.provider) {
284-
// Should not really get here, as the Pacts should have been sorted by provider
285-
throw IllegalArgumentException("You are using different Pacts with different providers for the same test" +
286-
" ('${acc.provider}') and '${pact.provider}'). A separate test (and ideally a separate test class)" +
287-
" should be used for each provider.")
288-
}
281+
val head = methods.first()
282+
val tail = methods.drop(1)
283+
val initial = lookupPact(providerInfo, head, context)
284+
val pact = tail.fold(initial) { acc, method ->
285+
val pact = lookupPact(providerInfo, method, context)
286+
287+
if (pact.provider != acc.provider) {
288+
// Should not really get here, as the Pacts should have been sorted by provider
289+
throw IllegalArgumentException("You are using different Pacts with different providers for the same test" +
290+
" ('${acc.provider}') and '${pact.provider}'). A separate test (and ideally a separate test class)" +
291+
" should be used for each provider.")
292+
}
289293

290-
if (pact.consumer != acc.consumer) {
291-
logger.warn {
292-
"WARNING: You are using different Pacts with different consumers for the same test " +
293-
"('${acc.consumer}') and '${pact.consumer}'). The second consumer will be ignored and dropped from " +
294-
"the Pact and the interactions merged. If this is not your intention, you need to create a " +
295-
"separate test for each consumer."
296-
}
294+
if (pact.consumer != acc.consumer) {
295+
logger.warn {
296+
"WARNING: You are using different Pacts with different consumers for the same test " +
297+
"('${acc.consumer}') and '${pact.consumer}'). The second consumer will be ignored and dropped from " +
298+
"the Pact and the interactions merged. If this is not your intention, you need to create a " +
299+
"separate test for each consumer."
297300
}
298-
299-
acc.mergeInteractions(pact.interactions) as BasePact
300301
}
302+
303+
acc.mergeInteractions(pact.interactions) as BasePact
301304
}
302305
store.put(key, pact)
303306
pact
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package au.com.dius.pact.consumer.junit5
2+
3+
import au.com.dius.pact.consumer.dsl.LambdaDsl.newJsonBody
4+
import au.com.dius.pact.consumer.dsl.PactBuilder
5+
import au.com.dius.pact.core.model.PactSpecVersion
6+
import au.com.dius.pact.core.model.V4Interaction
7+
import au.com.dius.pact.core.model.V4Pact
8+
import au.com.dius.pact.core.model.annotations.Pact
9+
import org.hamcrest.MatcherAssert.assertThat
10+
import org.hamcrest.Matchers.equalTo
11+
import org.hamcrest.Matchers.`is`
12+
import org.hamcrest.Matchers.notNullValue
13+
import org.junit.jupiter.api.TestTemplate
14+
import org.junit.jupiter.api.extension.ExtendWith
15+
16+
@ExtendWith(value = [PactConsumerTestExt::class])
17+
@PactTestFor(providerName = "checkout-service", providerType = ProviderType.ASYNCH, pactVersion = PactSpecVersion.V4)
18+
class TestTemplateTest {
19+
companion object {
20+
private val reservationBody = newJsonBody { o ->
21+
o.stringType("purchaseId", "111")
22+
o.stringType("name", "PURCHASE_STARTED")
23+
o.eachLike("products", 1) { items ->
24+
items.stringType("productID", "1")
25+
items.stringType("productType", "FLIGHT")
26+
items.stringType("availabilityId", "28e80c5987c6a242516ccdc004235b5e")
27+
}
28+
}.build()
29+
30+
private val cancelationBody = newJsonBody { o ->
31+
o.stringType("purchaseId", "111")
32+
o.stringType("reason", "user canceled")
33+
}.build()
34+
35+
@JvmStatic
36+
@Pact(consumer = "reservation-service", provider = "checkout-service")
37+
fun pactForReservationBooking(builder: PactBuilder): V4Pact {
38+
return builder
39+
.usingLegacyMessageDsl()
40+
.hasPactWith("checkout-service")
41+
.expectsToReceive("a purchase started message to book a reservation")
42+
.withContent(reservationBody)
43+
.toPact()
44+
}
45+
46+
@JvmStatic
47+
@Pact(consumer = "reservation-service", provider = "checkout-service")
48+
fun pactForCancellationBooking(builder: PactBuilder): V4Pact {
49+
return builder
50+
.usingLegacyMessageDsl()
51+
.hasPactWith("checkout-service")
52+
.expectsToReceive("a cancellation message to cancel a reservation")
53+
.withContent(cancelationBody)
54+
.toPact()
55+
}
56+
}
57+
58+
@TestTemplate
59+
fun testPactForReservationBooking(message: V4Interaction.AsynchronousMessage) {
60+
assertThat(message, `is`(notNullValue()))
61+
}
62+
}

0 commit comments

Comments
 (0)