Changed on:
17 Oct 2023
There are two ways to perform integration tests. The first involves creating the tests within the same project as your custom connector code. Alternatively, if your custom connector logic is in a separate module from your main class, you can create integration tests for that module instead.
When your integration tests are in module that doesn't have a main class, then you need to have a class like below in your src/test/java folder to allow Springboot tests to start the application for the integration tests.
1@EnableScheduling
2@SpringBootApplication
3public class ConnectorApplication {
4 /**
5 * Main method to start the connector
6 * @param args no arguments expected
7 */
8 public static void main(final String[] args) {
9 SpringApplication.run(ConnectorApplication.class, args);
10 }
11}
Language: java
Name: Example
Description:
[Warning: empty required content area]It is also required to create the necessary configuration files on your src/test/resources folder.
If you want logging, you will have to add a
`logback-spring.xml`
`it`
Connect SDK includes test modules to assist with integration tests:
The first step is to create the base integration test class where all dependencies are wired and set up for all of your integration tests. It also has some helper methods that can be used in your initialization of tests to set up the correct queues and secrets as well as wiremock stubs.
The base test class may or may not have a specific spring profile scope. It entirely depends on the integration test and coverage required.
In this approach, all tests implemented using this base class are not bound to run with AWS for example. To control what
`MessageSender`
1# To run the integration tests using SQS
2mvn clean integration-test -Dspring.profiles.active=connectors,it,aws,localstack
3
4AND/OR
5
6# To run the integration tests using Kafka
7mvn clean integration-test -Dspring.profiles.active=connectors,it,kafka
Language: plain_text
Name: Example
Description:
[Warning: empty required content area]Spring profile will ensure the correct bean of
`MessageSender`
1@Slf4j
2@Feature("Commerce Tools Integration Tests")
3@Testcontainers
4public abstract class CTBaseIntegrationTest extends BaseIntegrationTest {
5
6 @Autowired
7 protected MessageSender messageSender;
8
9 @Autowired
10 private SecretManagerContainerSetupService secretManagerContainerSetupService;
11 ...
Language: java
Name: Example
Description:
[Warning: empty required content area]Whenever the profile is specified, the spring profile is preset and there is no need to specify them at the time of the execution of the tests.
1mvn clean integration-test
Language: plain_text
Name: commands
Description:
[Warning: empty required content area]1@Slf4j
2@Feature("AWS specific Integration Tests")
3@Testcontainers
4@SpringBootTest(properties = "spring.profiles.active=connector,it,aws,localstack")
5public class AwsBaseIntegrationTest extends BaseIntegrationTest {
6
7 @Autowired
8 protected MessageSender messageSender;
9
10 @Autowired
11 private SecretManagerContainerSetupService secretManagerContainerSetupService;
12 ...
Language: java
Name: Example
Description:
[Warning: empty required content area]Here is a full example of a base integration test class:
1@Slf4j
2@Feature("AWS Integration Tests")
3@Testcontainers
4@SpringBootTest(properties = "spring.profiles.active=connector,it,aws,localstack")
5public class AwsBaseIntegrationTest extends BaseIntegrationTest {
6 public static final String EVENTS = "events";
7 public static final String BATCH = "batch";
8 private static final String SQS_BATCH = "SQS_BATCH";
9 private static final String SQS_EVENTS = "SQS_EVENTS";
10 @Autowired
11 protected MessageSender messageSender;
12 @Autowired
13 private SecretManagerContainerSetupService secretManagerContainerSetupService;
14
15 @BeforeAll
16 static void setup() {
17 //sets up the minimal required queues for the SDK, more can be added if necessary
18 System.setProperty(SQS_BATCH, BATCH);
19 System.setProperty(SQS_EVENTS, EVENTS);
20 startWiremockServer();
21 }
22
23 @AfterAll
24 static void tearDown() {
25 fluentWireMockServer.stop();
26 }
27
28 @BeforeEach
29 void testSetup() {
30 baseSetup(fluentWireMockServer);
31 }
32
33 @AfterEach
34 void afterTest() {
35 fluentWireMockServer.findAll(RequestPatternBuilder.allRequests()).forEach(request -> log.info(request.getAbsoluteUrl() + " " + request.getBodyAsString()));
36 fluentWireMockServer.resetAll();
37 }
38
39 @PostConstruct
40 private void setupSecretManager() throws IOException, InterruptedException {
41 //Sets up all required secrets used by your tests
42 secretManagerContainerSetupService.createSecret(
43 "fc/connect/testconnector/api/fluent/activeAccounts",
44 "{\"accounts\":[{\"name\":\"test\", \"retailers\":[1]}]}"
45 );
46 secretManagerContainerSetupService.createSecret(
47 "fc/connect/testconnector/TEST/api/fluent-account/1",
48 "{\"retailer\":\"1\", \"userName\":\"username\", \"password\":\"password\"}"
49 );
50 }
51}
Language: java
Name: Example
Description:
[Warning: empty required content area]Once you have done the above, you should be able to start writing tests. Any integration test class should extend the base test class created above.
1public class EventQueueIntegrationTest extends AwsBaseIntegrationTest {
2 private static final String EVENTS_DLQ = EVENTS + "-dlq";
3
4 @Autowired
5 private AmazonSQSAsync amazonSQSAsync;
6
7 @Test
8 void shouldPublishInvalidMessageToDlq() {
9 // when: publishing an invalid message to the events queue
10 messageSender.send(EVENTS, "hello");
11
12 // then: the message should be published to the dlq as thera are no handlers to process it
13 given()
14 .await()
15 .atMost(Duration.ofSeconds(2))
16 .untilAsserted(() -> Assertions.assertEquals(1, receiveMessagesFromQueue(EVENTS_DLQ, 5).size()));
17 }
18
19 private List<Message> receiveMessagesFromQueue(final String queue, final int messageNumber) {
20 final ReceiveMessageRequest request = new ReceiveMessageRequest(queue);
21 request.setVisibilityTimeout(2);
22 request.setWaitTimeSeconds(1);
23 request.setMaxNumberOfMessages(messageNumber);
24 return amazonSQSAsync.receiveMessage(request).getMessages();
25 }
26}
Language: java
Name: Example
Description:
[Warning: empty required content area]If you want to test any handler logic you may need to setup stubs and assert that wiremock is called. Some basic utility functions to assist with that are provided. Below is an example of how you might do this.
1import static com.fluentcommerce.connect.common.utils.IntegrationTestUtils.FLUENT_GRAPHQL_URL;
2import static com.fluentcommerce.connect.common.utils.IntegrationTestUtils.assertURLCalledAndBodyMatchesJson;
3import static com.fluentcommerce.connect.common.utils.IntegrationTestUtils.getResourceAsString;
4import static com.fluentcommerce.connect.common.utils.IntegrationTestUtils.setupGraphQL;
5import static com.fluentcommerce.connect.common.utils.IntegrationTestUtils.setupURL;
Language: java
Name: Example
Description:
[Warning: empty required content area]1 @Test
2 @DisplayName("Should create a customer and send to Fluent")
3 void shouldCreateCustomerInFluent() {
4 // given: a customer does not exist in Fluent
5 setupGraphQL(
6 fluentWireMockServer,
7 ".*GetCustomer.*",
8 "it/customer/fc/graphql/get_customer_empty_response.json"
9 );
10 setupGraphQL(fluentWireMockServer, ".*CreateCustomer.*", "it/common/fc/empty_response.json");
11 setupURL(ctWireMockServer, CT_GRAPHQL_URL, CT_CUSTOMER_QUERY_REGEX,
12 "it/customer/ct/graphql/get_customer_response.json"
13 );
14
15 // when: sending a customer message to the commercetools_events queue
16 messageSender.send(
17 COMMERCETOOLS_EVENTS,
18 getResourceAsString("it/message/customer_created.json")
19 );
20
21 // then: we should send a request to create a customer in Fluent
22 assertURLCalledAndBodyMatchesJson(
23 fluentWireMockServer,
24 FLUENT_GRAPHQL_URL,
25 ".*createCustomer.*",
26 getResourceAsString("it/customer/fc/graphql/create_customer_request_body.json")
27 );
28 }
Language: java
Name: Example
Description:
[Warning: empty required content area]Depending on how the integration tests were written (with or without spring profiles fixed), you may or may not need to specify the spring profiles when executing the integration tests.
Note that
`mvn test`
1# without specifying profiles
2mvn clean integration-test
3
4# with spring profiles
5mvn clean integration-test -Dspring.profiles.active=connectors,it,aws,localstack
6mvn clean integration-test -Dspring.profiles.active=connectors,it,kafka
Language: java
Name: Example
Description:
[Warning: empty required content area]You will also need to configure some properties depending which services you are using. To enable
`SecretsManager`
`S3`
`SQS`
1integration-test:
2 aws:
3 core-services:
4 enabled: true
5 queue:
6 enabled: true
Language: java
Name: Example
Description:
[Warning: empty required content area]If you want to use Kafka instead of AWS SQS, then just add the following to your configuration:
1integration-test:
2 kafka:
3 queue:
4 enabled: true
5 aws:
6 core-services:
7 enabled: true
Language: java
Name: Example
Description:
[Warning: empty required content area]Copyright © 2024 Fluent Retail Pty Ltd (trading as Fluent Commerce). All rights reserved. No materials on this docs.fluentcommerce.com site may be used in any way and/or for any purpose without prior written authorisation from Fluent Commerce. Current customers and partners shall use these materials strictly in accordance with the terms and conditions of their written agreements with Fluent Commerce or its affiliates.