Stub Runner for Messaging

Feature available since {messaging_version}

Stub Runner has the functionality to run the published stubs in memory. It can integrate with the following frameworks out of the box

  • Spring Integration

  • Spring Cloud Stream

  • Apache Camel

It also provides points of entry to integrate with any other solution on the market.

Stub triggering

To trigger a message it’s enough to use the StubTigger interface:

package io.codearte.accurest.stubrunner

interface StubTrigger {

        /**
         * Triggers an event by a given label for a given {@code groupid:artifactid} notation. You can use only {@code artifactId} too.
         *
         * Feature related to messaging.
         *
         * @return true - if managed to run a trigger
         */
        boolean trigger(String ivyNotation, String labelName)

        /**
         * Triggers an event by a given label.
         *
         * Feature related to messaging.
         *
         * @return true - if managed to run a trigger
         */
        boolean trigger(String labelName)

        /**
         * Triggers all possible events.
         *
         * Feature related to messaging.
         *
         * @return true - if managed to run a trigger
         */
        boolean trigger()

        /**
         * Returns a mapping of ivy notation of a dependency to all the labels it has.
         *
         * Feature related to messaging.
         */
        Map<String, Collection<String>> labels()
}

For convenience the StubFinder interface extends StubTrigger so it’s enough to use only one in your tests.

StubTrigger gives you the following options to trigger a message:

Trigger by label

stubFinder.trigger('return_book_1')
Trigger by group and artifact ids
stubFinder.trigger('io.codearte.accurest.stubs:camelService', 'return_book_1')
Trigger by artifact ids
stubFinder.trigger('camelService', 'return_book_1')
Trigger all messages
stubFinder.trigger()

Stub Runner Messaging Camel

Accurest Stub Runner’s messaging module gives you an easy way to integrate with Apache Camel. For the provided artifacts it will automatically download the stubs and register the required routes.

Adding it to the project

To use it you have to add the following dependency to your project (example for Gradle):

testCompile "io.codearte.accurest:stub-runner-messaging-camel:${accurestVersion}"

Examples

Stubs structure

Let us assume that we have the following Maven repository with a deployed stubs for the camelService application.

└── .m2
    └── repository
        └── io
            └── codearte
                └── accurest
                    └── stubs
                        └── camelService
                            ├── 0.0.1-SNAPSHOT
                            │   ├── camelService-0.0.1-SNAPSHOT.pom
                            │   ├── camelService-0.0.1-SNAPSHOT-stubs.jar
                            │   └── maven-metadata-local.xml
                            └── maven-metadata-local.xml

And the stubs contain the following structure:

├── META-INF
│   └── MANIFEST.MF
└── repository
    ├── accurest
    │   ├── bookDeleted.groovy
    │   ├── bookReturned1.groovy
    │   └── bookReturned2.groovy
    └── mappings

Let’s consider the following contracts (let' number it with 1):

io.codearte.accurest.dsl.GroovyDsl.make {
        label 'return_book_1'
        input {
                triggeredBy('bookReturnedTriggered()')
        }
        outputMessage {
                sentTo('jms:output')
                body('''{ "bookName" : "foo" }''')
                headers {
                        header('BOOK-NAME', 'foo')
                }
        }
}

and number 2

io.codearte.accurest.dsl.GroovyDsl.make {
        label 'return_book_2'
        input {
                messageFrom('jms:input')
                messageBody([
                                bookName: 'foo'
                ])
                messageHeaders {
                        header('sample', 'header')
                }
        }
        outputMessage {
                sentTo('jms:output')
                body([
                                bookName: 'foo'
                ])
                headers {
                        header('BOOK-NAME', 'foo')
                }
        }
}
Scenario 1 (no input message)

So as to trigger a message via the return_book_1 label we’ll use the StubTigger interface as follows

stubFinder.trigger('return_book_1')

Next we’ll want to listen to the output of the message sent to jms:output

Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000)

And the received message would pass the following assertions

receivedMessage != null
assertThatBodyContainsBookNameFoo(receivedMessage.in.body)
receivedMessage.in.headers.get('BOOK-NAME') == 'foo'
Scenario 2 (output triggered by input)

Since the route is set for you it’s enough to just send a message to the jms:output destination.

camelContext.createProducerTemplate().sendBodyAndHeaders('jms:input', new BookReturned('foo'), [sample: 'header'])

Next we’ll want to listen to the output of the message sent to jms:output

Exchange receivedMessage = camelContext.createConsumerTemplate().receive('jms:output', 5000)

And the received message would pass the following assertions

receivedMessage != null
assertThatBodyContainsBookNameFoo(receivedMessage.in.body)
receivedMessage.in.headers.get('BOOK-NAME') == 'foo'
Scenario 3 (input with no output)

Since the route is set for you it’s enough to just send a message to the jms:output destination.

camelContext.createProducerTemplate().sendBodyAndHeaders('jms:delete', new BookReturned('foo'), [sample: 'header'])

Stub Runner Messaging Integration

Accurest Stub Runner’s messaging module gives you an easy way to integrate with Spring Integration. For the provided artifacts it will automatically download the stubs and register the required routes.

Adding it to the project

To use it you have to add the following dependency to your project (example for Gradle):

testCompile "io.codearte.accurest:stub-runner-messaging-integration:${accurestVersion}"

Examples

Stubs structure

Let us assume that we have the following Maven repository with a deployed stubs for the integrationService application.

└── .m2
    └── repository
        └── io
            └── codearte
                └── accurest
                    └── stubs
                        └── integrationService
                            ├── 0.0.1-SNAPSHOT
                            │   ├── integrationService-0.0.1-SNAPSHOT.pom
                            │   ├── integrationService-0.0.1-SNAPSHOT-stubs.jar
                            │   └── maven-metadata-local.xml
                            └── maven-metadata-local.xml

And the stubs contain the following structure:

├── META-INF
│   └── MANIFEST.MF
└── repository
    ├── accurest
    │   ├── bookDeleted.groovy
    │   ├── bookReturned1.groovy
    │   └── bookReturned2.groovy
    └── mappings

Let’s consider the following contracts (let' number it with 1):

io.codearte.accurest.dsl.GroovyDsl.make {
        label 'return_book_1'
        input {
                triggeredBy('bookReturnedTriggered()')
        }
        outputMessage {
                sentTo('output')
                body('''{ "bookName" : "foo" }''')
                headers {
                        header('BOOK-NAME', 'foo')
                }
        }
}

and number 2

io.codearte.accurest.dsl.GroovyDsl.make {
        label 'return_book_2'
        input {
                messageFrom('input')
                messageBody([
                                bookName: 'foo'
                ])
                messageHeaders {
                        header('sample', 'header')
                }
        }
        outputMessage {
                sentTo('output')
                body([
                                bookName: 'foo'
                ])
                headers {
                        header('BOOK-NAME', 'foo')
                }
        }
}

and the following Spring Integration Route:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/integration"
                         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                         xmlns:beans="http://www.springframework.org/schema/beans"
                         xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/integration
                        http://www.springframework.org/schema/integration/spring-integration.xsd">


        <!-- REQUIRED FOR TESTING -->
        <bridge input-channel="output"
                        output-channel="outputTest"/>

        <channel id="outputTest">
                <queue/>
        </channel>

</beans:beans>
Scenario 1 (no input message)

So as to trigger a message via the return_book_1 label we’ll use the StubTigger interface as follows

stubFinder.trigger('return_book_1')

Next we’ll want to listen to the output of the message sent to output

AccurestMessage receivedMessage = messaging.receiveMessage('outputTest')

And the received message would pass the following assertions

receivedMessage != null
assertJsons(receivedMessage.payload)
receivedMessage.headers.get('BOOK-NAME') == 'foo'
Scenario 2 (output triggered by input)

Since the route is set for you it’s enough to just send a message to the output destination.

messaging.send(new BookReturned('foo'), [sample: 'header'], 'input')

Next we’ll want to listen to the output of the message sent to output

AccurestMessage receivedMessage = messaging.receiveMessage('outputTest')

And the received message would pass the following assertions

receivedMessage != null
assertJsons(receivedMessage.payload)
receivedMessage.headers.get('BOOK-NAME') == 'foo'
Scenario 3 (input with no output)

Since the route is set for you it’s enough to just send a message to the input destination.

messaging.send(new BookReturned('foo'), [sample: 'header'], 'delete')

Stub Runner Messaging Stream

Accurest Stub Runner’s messaging module gives you an easy way to integrate with Spring Stream. For the provided artifacts it will automatically download the stubs and register the required routes.

In Stub Runner’s integration with Stream the messageFrom or sentTo Strings are resolved first as a destination of a channel, and then if there is no such destination it’s resolved as a channel name.

Adding it to the project

To use it you have to add the following dependency to your project (example for Gradle):

testCompile "io.codearte.accurest:stub-runner-messaging-stream:${accurestVersion}"

Examples

Stubs structure

Let us assume that we have the following Maven repository with a deployed stubs for the streamService application.

└── .m2
    └── repository
        └── io
            └── codearte
                └── accurest
                    └── stubs
                        └── streamService
                            ├── 0.0.1-SNAPSHOT
                            │   ├── streamService-0.0.1-SNAPSHOT.pom
                            │   ├── streamService-0.0.1-SNAPSHOT-stubs.jar
                            │   └── maven-metadata-local.xml
                            └── maven-metadata-local.xml

And the stubs contain the following structure:

├── META-INF
│   └── MANIFEST.MF
└── repository
    ├── accurest
    │   ├── bookDeleted.groovy
    │   ├── bookReturned1.groovy
    │   └── bookReturned2.groovy
    └── mappings

Let’s consider the following contracts (let' number it with 1):

io.codearte.accurest.dsl.GroovyDsl.make {
        label 'return_book_1'
        input {
                triggeredBy('bookReturnedTriggered()')
        }
        outputMessage {
                sentTo('returnBook')
                body('''{ "bookName" : "foo" }''')
                headers {
                        header('BOOK-NAME', 'foo')
                }
        }
}

and number 2

io.codearte.accurest.dsl.GroovyDsl.make {
        label 'return_book_2'
        input {
                messageFrom('bookStorage')
                messageBody([
                                bookName: 'foo'
                ])
                messageHeaders {
                        header('sample', 'header')
                }
        }
        outputMessage {
                sentTo('returnBook')
                body([
                                bookName: 'foo'
                ])
                headers {
                        header('BOOK-NAME', 'foo')
                }
        }
}

and the following Spring configuration:

stubrunner.stubs.repository.root: classpath:m2repo/repository/
stubrunner.stubs.ids: io.codearte.accurest.stubs:streamService:0.0.1-SNAPSHOT:stubs

spring:
  cloud:
    stream:
      bindings:
        output:
          destination: returnBook
        input:
          destination: bookStorage
Scenario 1 (no input message)

So as to trigger a message via the return_book_1 label we’ll use the StubTrigger interface as follows

stubFinder.trigger('return_book_1')

Next we’ll want to listen to the output of the message sent to a channel whose destination is returnBook

AccurestMessage receivedMessage = messaging.receiveMessage('returnBook')

And the received message would pass the following assertions

receivedMessage != null
assertJsons(receivedMessage.payload)
receivedMessage.headers.get('BOOK-NAME') == 'foo'
Scenario 2 (output triggered by input)

Since the route is set for you it’s enough to just send a message to the bookStorage destination.

messaging.send(new BookReturned('foo'), [sample: 'header'], 'bookStorage')

Next we’ll want to listen to the output of the message sent to returnBook

AccurestMessage receivedMessage = messaging.receiveMessage('returnBook')

And the received message would pass the following assertions

receivedMessage != null
assertJsons(receivedMessage.payload)
receivedMessage.headers.get('BOOK-NAME') == 'foo'
Scenario 3 (input with no output)

Since the route is set for you it’s enough to just send a message to the output destination.

messaging.send(new BookReturned('foo'), [sample: 'header'], 'delete')