au.com.dius.pact.consumer.PactSpec.scala Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of pact-jvm-consumer-specs2_2.10 Show documentation
Show all versions of pact-jvm-consumer-specs2_2.10 Show documentation
pact-jvm-consumer-specs2
========================
## Specs2 Bindings for the pact-jvm library
## Dependency
In the root folder of your project in build.sbt add the line:
```scala
libraryDependencies += "au.com.dius" %% "pact-jvm-consumer-specs2" % "3.2.2"
```
or if you are using Gradle:
```groovy
dependencies {
testCompile "au.com.dius:pact-jvm-consumer-specs2_2.11:3.2.2"
}
```
__*Note:*__ `PactSpec` requires spec2 3.x. Also, for spray users there's an incompatibility between specs2 v3.x and spray.
Follow these instructions to resolve that problem: https://groups.google.com/forum/#!msg/spray-user/2T6SBp4OJeI/AJlnJuAKPRsJ
## Usage
To author a test, mix `PactSpec` into your spec
First we define a service client called `ConsumerService`. In our example this is a simple wrapper for `dispatch`, an HTTP client. The source code can be found in the test folder alongside the `ExamplePactSpec`.
Here is a simple example:
```
import au.com.dius.pact.consumer.PactSpec
class ExamplePactSpec extends Specification with PactSpec {
val consumer = "My Consumer"
val provider = "My Provider"
override def is = uponReceiving("a request for foo")
.matching(path = "/foo")
.willRespondWith(body = "{}")
.withConsumerTest { providerConfig =>
Await.result(ConsumerService(providerConfig.url).simpleGet("/foo"), Duration(1000, MILLISECONDS)) must beEqualTo(200, Some("{}"))
}
}
```
This spec will be run along with the rest of your specs2 unit tests and will output your pact json to
```
/target/pacts/<Consumer>_<Provider>.json
```
The newest version!
package au.com.dius.pact.consumer
import au.com.dius.pact.model.PactFragmentBuilder.PactWithAtLeastOneRequest
import au.com.dius.pact.model._
import org.specs2.execute.{AsResult, Failure, Result, Success}
import org.specs2.specification.create.FragmentsFactory
trait PactSpec extends FragmentsFactory {
val provider: String
val consumer: String
val providerState: Option[String] = None
def uponReceiving(description: String) = {
val pact = PactFragment.consumer(consumer).hasPactWith(provider)
if (providerState.isDefined) pact.given(providerState.get).uponReceiving(description)
else pact.uponReceiving(description)
}
implicit def liftFragmentBuilder(builder: PactWithAtLeastOneRequest): ReadyForTest = {
new ReadyForTest(PactFragment(builder.consumer, builder.provider, builder.interactions))
}
implicit def pactVerificationAsResult: AsResult[VerificationResult] = {
new AsResult[VerificationResult] {
def asResult(test: => VerificationResult): Result = {
test match {
case PactVerified => Success()
case PactMismatch(results, error) => Failure(PrettyPrinter.print(results))
case UserCodeFailed(e) => Failure(m = s"The user code failed: $e")
case PactError(e) => Failure(m = s"There was an unexpected exception: ${e.getMessage}", stackTrace = e.getStackTrace.toList)
}
}
}
}
class ReadyForTest(pactFragment: PactFragment) {
def withConsumerTest(test: MockProviderConfig => Result) = {
val config = MockProviderConfig.createDefault(PactSpecVersion.V2)
val description = s"Consumer '${pactFragment.consumer.getName}' has a pact with Provider '${pactFragment.provider.getName}': " +
pactFragment.interactions.map { i => i.getDescription }.mkString(" and ") + sys.props("line.separator")
fragmentFactory.example(description, {
pactFragment.duringConsumerSpec(config)(test(config), verify)
})
}
}
case class ConsumerTestFailed(r: Result) extends RuntimeException
def verify: ConsumerTestVerification[Result] = { r: Result =>
if (r.isSuccess) {
None
} else {
Some(r)
}
}
}