[[features-stub-runner-junit]]
= Stub Runner JUnit Rule and Stub Runner JUnit5 Extension

include::partial$_attributes.adoc[]

Stub Runner comes with a JUnit rule that lets you can download and run stubs for a given
group and artifact ID, as the following example shows:

====
[source,java,indent=0]
----
include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit4/StubRunnerRuleJUnitTest.java[tags=classrule]
----
====

A `StubRunnerExtension` is also available for JUnit 5. `StubRunnerRule` and
`StubRunnerExtension` work in a very similar fashion. After the rule or extension is
called, 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 or the provided port
- Feed the WireMock server with all JSON files that are valid WireMock definitions
- Send messages (remember to pass an implementation of `MessageVerifierSender` interface)

Stub Runner uses the 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` and `StubRunnerExtension` implement the `StubFinder`, they let
you find the started stubs, as the following example shows:

====
[source,groovy,indent=0]
----
include::{stubrunner_core_path}/src/main/java/org/springframework/cloud/contract/stubrunner/StubFinder.java[lines=16..-1]
----
====

The following examples provide more detail about using Stub Runner:

====
[source,groovy,indent=0,subs="verbatim",role="primary"]
.Spock
----
include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit4/StubRunnerRuleSpec.groovy[tags=classrule]
----

[source,java,indent=0,subs="verbatim",role="secondary"]
.Junit 4
----
include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit4/StubRunnerRuleJUnitTest.java[tags=test]
----

[source,java,indent=0,subs="verbatim",role="secondary"]
.Junit 5
----
include::{stubrunner_core_path}/src/test/java/org/springframework/cloud/contract/stubrunner/junit/StubRunnerJUnit5ExtensionTests.java[tags=extension]
----
====

See the xref:../project-features-stubrunner/stub-runner-common.adoc#features-stub-runner-common-properties-junit-spring[Common Properties for JUnit and Spring] for more information on
how to apply global configuration of Stub Runner.

IMPORTANT: To use the JUnit rule or JUnit 5 extension together with messaging, you have to provide an implementation of the
`MessageVerifierSender` and `MessageVerifierReceiver` interface to the rule builder (for example, `rule.messageVerifierSender(new MyMessageVerifierSender())`).
If you do not do this, then, whenever you try to send a message, an exception is thrown.

[[features-stub-runner-rule-maven-settings]]
== Maven Settings

The stub downloader honors Maven settings for a different local repository folder.
Authentication details for repositories and profiles are currently not taken into account,
so you need to specify it by using the properties mentioned above.

[[features-stub-runner-rule-fixed-ports]]
== 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 is to use the fluent API of
JUnit rule.

[[features-stub-runner-rule-fluent-api]]
== Fluent API

When using the `StubRunnerRule` or `StubRunnerExtension`, you can add a stub to download
and then pass the port for the last downloaded stub. The following example shows how to do so:

====
[source,java,indent=0]
----
include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit4/StubRunnerRuleCustomPortJUnitTest.java[tags=classrule_with_port]
----
====

For the preceding example, the following test is valid:

====
[source,java,indent=0]
----
include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/junit4/StubRunnerRuleCustomPortJUnitTest.java[tags=test_with_port]
----
====

[[features-stub-runner-rule-spring]]
== Stub Runner with Spring

Stub Runner with Spring sets up Spring configuration of the Stub Runner project.

By providing a list of stubs inside your configuration file, 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 follows:

====
[source,groovy,indent=0]
----
include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/StubRunnerConfigurationSpec.groovy[tags=test]
----
====

Doing so depends on the following configuration file:

====
[source,yml,indent=0]
----
include::{stubrunner_core_path}/src/test/resources/application-test.yml[tags=test]
----
====

Instead of using the properties, you can also use the properties inside the `@AutoConfigureStubRunner`.
The following example achieves the same result by setting values on the annotation:

====
[source,groovy,indent=0]
----
include::{stubrunner_core_path}/src/test/groovy/org/springframework/cloud/contract/stubrunner/spring/cloud/consul/StubRunnerSpringCloudConsulAutoConfigurationSpec.groovy[tags=autoconfigure]
----
====

Stub Runner Spring registers environment variables in the following manner
for every registered WireMock server. The following example shows Stub Runner IDs for
`com.example:thing1` and `com.example:thing2`:

- `stubrunner.runningstubs.thing1.port`
- `stubrunner.runningstubs.com.example.thing1.port`
- `stubrunner.runningstubs.thing2.port`
- `stubrunner.runningstubs.com.example.thing2.port`

You can reference these values in your code.

You can also use the `@StubRunnerPort` annotation to inject the port of a running stub.
The value of the annotation can be the `groupid:artifactid` or only the `artifactid`.
The following example works shows Stub Runner IDs for
`com.example:thing1` and `com.example:thing2`.

====
[source,java,indent=0]
----
@StubRunnerPort("thing1")
int thing1Port;
@StubRunnerPort("com.example:thing2")
int thing2Port;
----
====

