Made with Spring, Cucumber and Gherkin !
To test your REST API with cucumber, gherkin please use this library
- Spring Boot / Spring cloud
- Cucumber / Gherkin
- Jayway JsonPath
<dependency>
<groupId>fr.redfroggy.test.bdd</groupId>
<artifactId>cucumber-messaging</artifactId>
</dependency>
Run npm install
to add commitlint + husky
@user @messaging
Feature: Users messaging tests
Background:
Given I set contentType queue message header to application/json
Scenario: Should valid user
When I mock third party call GET /public/characters/2?sessionId=43233333 with return code 200 and body: {"comicName": "IronMan", "city": "New York", "mainColor": ["red", "yellow"]}
And I set queue message body to {"id": "2","firstName":"Bruce","lastName":"Wayne","age":"50", "sessionIds": ["43233333", "45654345"]}
And I set queue message body path $.age to 51
And I set X_TOKEN_ID queue message header to 1234
And I PUSH to queue input-valid-user
And I POLL first message from queue output-valid-user
Then queue message body should be valid json
And queue message body should contain Wayne
And queue message body path $.id should exist
And queue message body path $.relatedTo should not exist
And queue message body path $.status should not be INVALID
And queue message body path $.status should be VALID
And queue message body path $.firstName should be Bruce
And queue message body path $.lastName should be Wayne
And queue message body path $.age should be 51
And queue message body is typed as array for path $.sessionIds
And queue message body is typed as array using path $.sessionIds with length 2
And queue message body path $.sessionIds should be ["43233333", "45654345"]
And queue message body path $.sessionIds should not be []
And queue message header contentType should not be application/xml
And queue message header X_TOKEN_ID should exist
And queue message header X_TOKEN_ID should be 1234
And I store the value of queue message header X_TOKEN_ID as tokenId in scenario scope
And I store the value of queue message path $.sessionIds.[0] as firstSessionId in scenario scope
Scenario: Should valid user using json file as body
Given I mock third party call GET /public/characters/15948349393 with return code 200, content type: application/json and file: fixtures/bruce_wayne_marvel_api.fixture.json
When I set queue message body with file fixtures/bruce-banner.user.json
And I PUSH to queue input-valid-user
And I POLL first message from queue output-valid-user
Then queue message body should be valid json
And queue message body path $.firstName should be Bruce
And queue message body path $.lastName should be Banner
Scenario: Should not be able to read multiple times from queue when polling
When I mock third party call GET /public/characters/2 with return code 200 and body: {"comicName": "IronMan", "city": "New York", "mainColor": ["red", "yellow"]}
And I set queue message body to {"id": "2","firstName":"Bruce","lastName":"Wayne","age":"50", "sessionIds": [`$firstSessionId`]}
And queue value of scenario variable tokenId should be 1234
And I set X_TOKEN_ID queue message header to `$tokenId`
And I PUSH to queue input-valid-user
And I POLL first message from queue output-valid-user
Then queue message body path $.status should be VALID
And queue message header X_TOKEN_ID should be 1234
And queue value of scenario variable firstSessionId should be 43233333
When I POLL first message from queue output-valid-user
And queue should have 0 messages left
Scenario: Should be able to read multiple times from queue when peeking
When I mock third party call GET /public/characters/2 with return code 200 and body: {"comicName": "IronMan", "city": "New York", "mainColor": ["red", "yellow"]}
And I set queue message body to {"id": "2","firstName":"Bruce","lastName":"Wayne","age":"50"}
And I PUSH to queue input-valid-user
And I PEEK first message from queue output-valid-user
Then queue message body path $.status should be VALID
When I PEEK first message from queue output-valid-user
And queue should have 1 messages left
Then queue message body path $.status should be VALID
And queue message header X_TOKEN_ID should not exist
You can look at the users.feature file for a more detailed example.
- You can use the following step to store data from a json response body to a shared context:
And I store the value of queue message path $.id as idUser in scenario scope
- You can use the following step to store data from a response header to a shared context:
And I store the value of queue message header Authorization as authHeader in scenario scope
- The result of the JsonPath
$.id
will be stored in theidUser
variable. - To reuse this variable in another step, you can do:
When I PUSH to queue valid-user`$idUser`
And I set X-USER-ID queue message header to `$idUser`
You can see a usage example in the test folder.
@RunWith(Cucumber.class)
@CucumberOptions(
plugin = {"pretty"},
features = "src/test/resources/features",
glue = {"fr.redfroggy.bdd.messaging.glue"})
public class CucumberTest {
}
- Set the glue property to
fr.redfroggy.bdd.messaging.glue
and add your package glue. - Set your
features
folder property - Add your
.feature
files under yourfeatures
folder - In your
.feature
files you should have access to all the steps defined in the MessagingBddStepDefinition file.
It is mandatory to have a class annotated with @CucumberContextConfiguration
to be able to run the tests.
This class must be in the same glue
package that you've specified in the CucumberTest
class.
@CucumberContextConfiguration
@SpringBootTest(classes = Application.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class DefaultStepDefinition {
}
If you need to mock a third party API, you can use the following steps:
I mock third party call (.*) (.*) with return code (.*), content type: (.*) and body: (.*)
# Example: I mock third party call GET /public/characters/1?format=json with return code 200, content type: application/json and body: {"comicName": "IronMan", "city": "New York", "mainColor": ["red", "yellow"]}
I mock third party call (.*) (.*) with return code (.*), content type: (.*) and file: (.*)
# Example: I mock third party call GET /public/characters/2 with return code 200, content type: application/json and file: fixtures/bruce_wayne_marvel_api.fixture.json
It relies on WireMock for stubbing api calls.
By default, the wiremock port is 8888
, if you need to override it you need to change the
redfroggy.cucumber.restapi.wiremock.port
property in your project.
$ mvn test