Skip to content

Commit

Permalink
refactor: renamed AmqpTarget to MessageTarget #383
Browse files Browse the repository at this point in the history
  • Loading branch information
Ronald Holshausen committed May 27, 2020
1 parent 218d516 commit c04f174
Show file tree
Hide file tree
Showing 6 changed files with 162 additions and 8 deletions.
10 changes: 5 additions & 5 deletions provider/junit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ no parameters or a single Map parameter.
}
```

## Example of AMQP Message test
## Example of Message test

```java
@RunWith(PactRunner.class) // Say JUnit to run tests with custom Runner
Expand All @@ -76,7 +76,7 @@ no parameters or a single Map parameter.
public class ConfirmationKafkaContractTest {

@TestTarget // Annotation denotes Target that will be used for tests
public final Target target = new AmqpTarget(); // Out-of-the-box implementation of Target (for more information take a look at Test Target section)
public final Target target = new MessageTarget(); // Out-of-the-box implementation of Target (for more information take a look at Test Target section)

@BeforeClass //Method will be run once: before whole contract test suite
public static void setUpService() {
Expand Down Expand Up @@ -382,10 +382,10 @@ that will play pacts as http request and assert response from service by matchin

You can also specify the protocol, defaults to "http".

### AmqpTarget
### MessageTarget

`au.com.dius.pact.provider.junit.target.AmqpTarget` - out-of-the-box implementation of `au.com.dius.pact.provider.junit.target.Target`
that will play pacts as an AMQP message and assert response from service by matching rules from pact.
`au.com.dius.pact.provider.junit.target.MessageTarget` - out-of-the-box implementation of `au.com.dius.pact.provider.junit.target.Target`
that will play pacts as an message and assert response from service by matching rules from pact.

**Note for Maven users:** If you use Maven to run your tests, you will have to make sure that the Maven Surefire plugin is at least
version 2.22.1 uses an isolated classpath.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import java.util.function.Supplier
* the performance cost
* @param packagesToScan List of JVM packages
*/
@Deprecated("Use MessageTarget")
open class AmqpTarget @JvmOverloads constructor(
private val packagesToScan: List<String> = emptyList(),
private val classLoader: ClassLoader? = null
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package au.com.dius.pact.provider.junit.target

import au.com.dius.pact.core.model.DirectorySource
import au.com.dius.pact.core.model.Interaction
import au.com.dius.pact.core.model.PactBrokerSource
import au.com.dius.pact.core.model.PactSource
import au.com.dius.pact.provider.ConsumerInfo
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.PactVerification
import au.com.dius.pact.provider.ProviderInfo
import au.com.dius.pact.provider.ProviderVerifier
import au.com.dius.pact.provider.VerificationResult
import au.com.dius.pact.provider.junitsupport.Provider
import mu.KLogging
import java.net.URLClassLoader
import java.util.function.Function
import java.util.function.Supplier

/**
* Out-of-the-box implementation of [Target], that run [Interaction] against message pact and verify response
* By default it will scan all packages for annotated methods, but a list of packages can be provided to reduce
* the performance cost
* @param packagesToScan List of JVM packages
*/
open class MessageTarget @JvmOverloads constructor(
private val packagesToScan: List<String> = emptyList(),
private val classLoader: ClassLoader? = null
) : BaseTarget() {

/**
* {@inheritDoc}
*/
override fun testInteraction(
consumerName: String,
interaction: Interaction,
source: PactSource,
context: Map<String, Any>
) {
val provider = getProviderInfo(source)
val consumer = consumerInfo(consumerName, source)
val verifier = setupVerifier(interaction, provider, consumer, source)

val result = verifier.verifyResponseByInvokingProviderMethods(provider, consumer, interaction,
interaction.description, mutableMapOf())
reportTestResult(result, verifier)

try {
if (result is VerificationResult.Failed) {
verifier.displayFailures(listOf(result))
throw AssertionError(verifier.generateErrorStringFromVerificationResult(listOf(result)))
}
} finally {
verifier.finaliseReports()
}
}

override fun setupVerifier(
interaction: Interaction,
provider: IProviderInfo,
consumer: IConsumerInfo,
pactSource: PactSource?
): IProviderVerifier {
val verifier = ProviderVerifier()
verifier.projectClasspath = Supplier {
logger.debug { "Classloader = ${this.classLoader}" }
when (this.classLoader) {
is URLClassLoader -> this.classLoader.urLs.asList()
else -> emptyList()
}
}
val defaultProviderMethodInstance = verifier.providerMethodInstance
verifier.providerMethodInstance = Function { m ->
if (m.declaringClass == testTarget.javaClass) {
testTarget
} else {
defaultProviderMethodInstance.apply(m)
}
}

setupReporters(verifier)

verifier.initialiseReporters(provider)
verifier.reportVerificationForConsumer(consumer, provider, pactSource)

if (interaction.providerStates.isNotEmpty()) {
for ((name) in interaction.providerStates) {
verifier.reportStateForInteraction(name.toString(), provider, consumer, true)
}
}

verifier.reportInteractionDescription(interaction)

return verifier
}

override fun getProviderInfo(source: PactSource): ProviderInfo {
val provider = testClass.getAnnotation(Provider::class.java)
val providerInfo = ProviderInfo(provider.value)
providerInfo.verificationType = PactVerification.ANNOTATED_METHOD
providerInfo.packagesToScan = packagesToScan

if (source is PactBrokerSource<*>) {
val (_, _, _, pacts) = source
providerInfo.consumers = pacts.entries.flatMap { e ->
e.value.map { p -> ConsumerInfo(e.key.name, p) }
}.toMutableList()
} else if (source is DirectorySource<*>) {
val (_, pacts) = source
providerInfo.consumers = pacts.entries.map { e -> ConsumerInfo(e.value.consumer.name, e.value) }.toMutableList()
}

return providerInfo
}

companion object : KLogging()
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
package au.com.dius.pact.provider.junit;

import au.com.dius.pact.provider.PactVerifyProvider;
import au.com.dius.pact.provider.junit.target.MessageTarget;
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.junit.target.AmqpTarget;
import au.com.dius.pact.provider.junitsupport.target.Target;
import au.com.dius.pact.provider.junitsupport.target.TestTarget;
import org.junit.runner.RunWith;

@RunWith(PactRunner.class)
@Provider("AmqpProvider")
@PactFolder("src/test/resources/amqp_pacts")
public class AmqpTest {
public class MessageTest {
@TestTarget
public final Target target = new AmqpTarget();
public final Target target = new MessageTarget();

@State("SomeProviderState")
public void someProviderState() {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import java.util.function.Function
* Target for message verification that supports a spring application context. For each annotated method, the owning
* bean will be looked up from the application context
*/
@Deprecated("Use SpringAwareMessageTarget instead")
open class SpringAwareAmqpTarget : AmqpTarget(), BeanFactoryAware {
private lateinit var beanFactory: BeanFactory

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package au.com.dius.pact.provider.spring.target

import au.com.dius.pact.core.model.Interaction
import au.com.dius.pact.core.model.PactSource
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.junit.target.MessageTarget
import org.springframework.beans.factory.BeanFactory
import org.springframework.beans.factory.BeanFactoryAware
import java.util.function.Function

/**
* Target for message verification that supports a spring application context. For each annotated method, the owning
* bean will be looked up from the application context
*/
open class SpringAwareMessageTarget : MessageTarget(), BeanFactoryAware {
private lateinit var beanFactory: BeanFactory

override fun setBeanFactory(beanFactory: BeanFactory) {
this.beanFactory = beanFactory
}

override fun setupVerifier(
interaction: Interaction,
provider: IProviderInfo,
consumer: IConsumerInfo,
pactSource: PactSource?
): IProviderVerifier {
val verifier = super.setupVerifier(interaction, provider, consumer, pactSource)
verifier.providerMethodInstance = Function { m -> beanFactory.getBean(m.declaringClass) }
return verifier
}
}

0 comments on commit c04f174

Please sign in to comment.