=== Stub Runner Core
Runs stubs for service collaborators. Treating stubs as contracts of services allows to use stub-runner as an implementation of
http://martinfowler.com/articles/consumerDrivenContracts.html[Consumer Driven Contracts].
Stub Runner allows you to automatically download the stubs of the provided dependencies, start WireMock servers for them and feed them with proper stub definitions.
For messaging, special stub routes are defined.
==== Running stubs
===== Running using main app
You can set the following options to the main class:
[source,groovy,indent=0]
----
-c, --classifier Suffix for the jar containing stubs (e.
g. 'stubs' if the stub jar would
have a 'stubs' classifier for stubs:
foobar-stubs ). Defaults to 'stubs'
(default: stubs)
--maxPort, --maxp <Integer> Maximum port value to be assigned to
the WireMock instance. Defaults to
15000 (default: 15000)
--minPort, --minp <Integer> Minimum port value to be assigned to
the WireMock instance. Defaults to
10000 (default: 10000)
-p, --password Password to user when connecting to
repository
--phost, --proxyHost Proxy host to use for repository
requests
--pport, --proxyPort [Integer] Proxy port to use for repository
requests
-r, --root Location of a Jar containing server
where you keep your stubs (e.g. http:
//nexus.
net/content/repositories/repository)
-s, --stubs Comma separated list of Ivy
representation of jars with stubs.
Eg. groupid:artifactid1,groupid2:
artifactid2:classifier
-u, --username Username to user when connecting to
repository
--wo, --workOffline Switch to work offline. Defaults to
'false'
----
===== HTTP Stubs
Stubs are defined in JSON documents, whose syntax is defined in http://wiremock.org/stubbing.html[WireMock documentation]
Example:
[source,javascript,indent=0]
----
{
"request": {
"method": "GET",
"url": "/ping"
},
"response": {
"status": 200,
"body": "pong",
"headers": {
"Content-Type": "text/plain"
}
}
}
----
===== Viewing registered mappings
Every stubbed collaborator exposes list of defined mappings under `__/admin/` endpoint.
===== Messaging Stubs
Depending on the provided Stub Runner dependency and the DSL the messaging routes are automatically set up.
=== Stub Runner JUnit Rule
Stub Runner comes with a JUnit rule thanks to which you can very easily download and run stubs for given group and artifact id:
[source,java,indent=0]
----
include::src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleJUnitTest.java[tags=classrule]
----
After that rule gets executed Stub Runner connects to your Maven repository and for the given list of dependencies tries to:
- download them
- cache them locally
- unzip them to a temporary folder
- start a WireMock server for each Maven dependency on a random port from the provided range of ports / provided port
- feed the WireMock server with all JSON files that are valid WireMock definitions
Stub Runner uses https://wiki.eclipse.org/Aether[Eclipse Aether] mechanism to download the Maven dependencies.
Check their https://wiki.eclipse.org/Aether[docs] for more information.
Since the `StubRunnerRule` implements the `StubFinder` it allows you to find the started stubs:
[source,groovy,indent=0]
----
include::src/main/java/org/springframework/cloud/contract/stubrunner/StubFinder.java[]
----
Example of usage in Spock tests:
[source,groovy,indent=0]
----
include::src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleSpec.groovy[tags=classrule]
----
Example of usage in JUnit tests:
[source,java,indent=0]
----
include::src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleJUnitTest.java[tags=test]
----
Check the *Common properties for JUnit and Spring* for more information on how to apply global configuration of Stub Runner.
==== Providing fixed ports
You can also run your stubs on fixed ports. You can do it in two different ways. One is to pass it in the properties, and the other via fluent API of
JUnit rule.
==== Fluent API
When using the `StubRunnerRule` you can add a stub to download and then pass the port for the last downloaded stub.
[source,java,indent=0]
----
include::src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleCustomPortJUnitTest.java[tags=classrule_with_port]
----
You can see that for this example the following test is valid:
[source,java,indent=0]
----
include::src/test/groovy/org/springframework/cloud/contract/stubrunner/junit/StubRunnerRuleCustomPortJUnitTest.java[tags=test_with_port]
----
==== Stub Runner with Spring
Sets up Spring configuration of the Stub Runner project.
By providing a list of stubs inside your configuration file the Stub Runner automatically downloads
and registers in WireMock the selected stubs.
If you want to find the URL of your stubbed dependency you can autowire the `StubFinder` interface and use
its methods as presented below:
[source,groovy,indent=0]
----
include::src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfigurationSpec.groovy[tags=test]
----
for the following configuration file:
[source,yml,indent=0]
----
include::src/test/resources/application-test.yml[]
----
Instead of using the properties you can also use the properties inside the `@AutoConfigureStubRunner`.
Below you can find an example of achieving the same result by setting values on the annotation.
[source,groovy,indent=0]
----
include::src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfigurationSpec.groovy[tags=autoconfigure]
----
Stub Runner Spring registers environment variables in the following manner
for every registered WireMock server. Example for Stub Runner ids
`com.example:foo`, `com.example:bar`.
- `stubrunner.runningstubs.foo.port`
- `stubrunner.runningstubs.bar.port`
Which you can reference in your code.
=== Stub Runner Spring Cloud
Stub Runner can integrate with Spring Cloud.
==== Stubbing Service Discovery
The most important feature of `Stub Runner Spring Cloud` is the fact that it's stubbing
- `DiscoveryClient`
- `Ribbon` `ServerList`
that means that regardless of the fact whether you're using Zookeeper, Consul, Eureka or anything else, you don't need that in your tests.
We're starting WireMock instances of your dependencies and we're telling your application whenever you're using `Feign`, load balanced `RestTemplate`
or `DiscoveryClient` directly, to call those stubbed servers instead of calling the real Service Discovery tool.
For example this test will pass
[source,groovy,indent=0]
----
include::src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/StubRunnerSpringCloudAutoConfigurationSpec.groovy[tags=test]
----
for the following configuration file
[source,yml,indent=0]
----
include::src/test/resources/application.yml[]
----
==== Additional Configuration
You can match the artifactId of the stub with the name of your app by using the `stubrunner.idsToServiceIds:` map.
You can disable Stub Runner Ribbon support by providing: `stubrunner.cloud.ribbon.enabled` equal to `false`
You can disable Stub Runner support by providing: `stubrunner.cloud.enabled` equal to `false`
TIP: By default all service discovery will be stubbed. That means that regardless of the fact if you have
an existing `DiscoveryClient` its results will be ignored. However, if you want to reuse it, just set
`stubrunner.cloud.delegate.enabled` to `true` and then your existing `DiscoveryClient` results will be
merged with the stubbed ones.
=== Stub Runner Boot Application
Spring Cloud Contract Verifier Stub Runner Boot is a Spring Boot application that exposes REST endpoints to
trigger the messaging labels and to access started WireMock servers.
One of the use-cases is to run some smoke (end to end) tests on a deployed application. You can read
more about this in the http://toomuchcoding.com/blog/2015/09/27/microservice-deployment/["Microservice Deployment" article at Too Much Coding blog.]
==== How to use it?
Just add the
[source,groovy,indent=0]
----
compile "org.springframework.cloud:spring-cloud-starter-stub-runner"
----
Annotate a class with `@EnableStubRunnerServer`, build a fat-jar and you're ready to go!
For the properties check the *Stub Runner Spring* section.
==== Endpoints
===== HTTP
- GET `/stubs` - returns a list of all running stubs in `ivy:integer` notation
- GET `/stubs/{ivy}` - returns a port for the given `ivy` notation (when calling the endpoint `ivy` can also be `artifactId` only)
===== Messaging
For Messaging
- GET `/triggers` - returns a list of all running labels in `ivy : [ label1, label2 ...]` notation
- POST `/triggers/{label}` - executes a trigger with `label`
- POST `/triggers/{ivy}/{label}` - executes a trigger with `label` for the given `ivy` notation (when calling the endpoint `ivy` can also be `artifactId` only)
==== Example
[source,groovy,indent=0]
----
include::src/test/groovy/org/springframework/cloud/contract/stubrunner/server/StubRunnerBootSpec.groovy[tags=boot_usage]
----
==== Stub Runner Boot with Service Discovery
One of the possibilities of using Stub Runner Boot is to use it as a feed of stubs for "smoke-tests". What does it mean?
Let's assume that you don't want to deploy 50 microservice to a test environment in order
to check if your application is working fine. You've already executed a suite of tests during the build process
but you would also like to ensure that the packaging of your application is fine. What you can do
is to deploy your application to an environment, start it and run a couple of tests on it to see if
it's working fine. We can call those tests smoke-tests since their idea is to check only a handful
of testing scenarios.
The problem with this approach is such that if you're doing microservices most likely you're
using a service discovery tool. Stub Runner Boot allows you to solve this issue by starting the
required stubs and register them in a service discovery tool. Let's take a look at an example of
such a setup with Eureka. Let's assume that Eureka was already running.
[source,java,indent=0]
----
include::src/test/groovy/org/springframework/cloud/contract/stubrunner/serverexamples/StubRunnerBootEurekaExample.java[tags=stubrunnereureka]
----
As you can see we want to start a Stub Runner Boot server `@EnableStubRunnerServer`, enable Eureka client `@EnableEurekaClient`
and we want to have the stub runner feature turned on `@AutoConfigureStubRunner`.
Now let's assume that we want to start this application so that the stubs get automatically registered.
We can do it by running the app `java -jar ${SYSTEM_PROPS} stub-runner-boot-eureka-example.jar` where
`${SYSTEM_PROPS}` would contain the following list of properties
[source,bash,indent=0]
----
include::src/test/groovy/org/springframework/cloud/contract/stubrunner/serverexamples/StubRunnerBootEurekaExample.java[tags=stubrunnereureka_args]
----
That way your deployed application can send requests to started WireMock servers via the service
discovery. Most likely points 1-3 could be set by default in `application.yml` cause they are not
likely to change. That way you can provide only the list of stubs to download whenever you start
the Stub Runner Boot.