This project shows how to set up an spring boot project for running Integration test using TestContainers and Wiremock.
Next section shows application processing flow its dependencies:
Main goal for this project, is receive a HTTP Request and process following next steps:
-
Persist request: Save data request with
NEW
state into database. -
Get merchant configurations: Call an external web service to get the merchant configuration.
-
Evaluate fraud: If merchant has enabled fraud validation option, it calls Fraud Control web service (update the request to
EVALUATED
status in database). -
WebHook for final state: If merchant has enabled web hook notifications, it sends an http post to the merchant web page. (update the request to
NOTIFIED
status in database).
NOTE:
- If one error occurs, system update the record in
ERROR
state and return a HTTP response with error message.
This project process a request using next 4 dependencies:
-
ConfigurationService: External rest web service for getting up merchant configurations. Implementation using declarative Feign client.
-
FraudControlService: External rest web service for evaluation/scoring fraud risk. Implementation using Spring RestTemplate.
-
MerchantWebHook: External merchant web endpoint for receiving HTTP notifications. Implementation using Spring RestTemplate.
-
DBMS: Relational database managment system for persisting process flow and process result. This project uses Postgres.
This section shows implementation integration test.
Integration test using TestContainers
. Find implementation in RepositoryIntegrationTest.java class.
Header annotation class has configuration for running jpa integration test:
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@ContextConfiguration(initializers = RepositoryIntegrationTest.Initializer.class)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@Testcontainers
public class RepositoryIntegrationTest {
- Annotation for a JPA test that focuses only on JPA components.
NONE
configuration do not replace the application default DataSource.
- Annotation to find all fields that are annotated with @Container and calls their container lifecycle methods.
- Spring Initializer for starting Postgres database container.
protected static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
TestPropertyValues
.of("spring.datasource.url=" + postgreSQLContainer.getJdbcUrl(),
"spring.datasource.username=" + postgreSQLContainer.getUsername(),
"spring.datasource.password=" + postgreSQLContainer.getPassword())
.applyTo(configurableApplicationContext);
}
}
Integration test using Wiremock
. Find implementation in AbstractClientConfiguration.java class.
Header annotation class has configuration for web client integration test:
@ContextConfiguration(classes = { AbstractClientConfiguration.ContextConfiguration.class })
@SpringBootTest(
properties = { "app.config-service.base-path=","app.fraud-service.base-path=http://localhost:${wiremock.server.port}/evaluate" },
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
classes = {FraudEvaluationClient.class, WebHookClient.class, RestTemplate.class })
@AutoConfigureWireMock(port = 0, stubs = "classpath*:/wiremock/**/mappings/**/*.json", files = "classpath:/wiremock")
public class AbstractClientConfiguration {
- Define which Spring @Configuration to load.
- ContextConfiguration configuration class for prepare Feign clients and RestTemplateBuilder.
- This annotation allow us to create the ApplicationContext used in integration tests via SpringApplication.
- we override the external services base path for using
WireMock
endpoints.
- Annotation to start a mock web server with our stubs and mapping definitions.
End to End testing using Wiremock
and TestContainers
. Find implementation in AbtractIntegrationTest.java class.
Header annotation class has configuration for running End to End test:
@ContextConfiguration(initializers = AbtractIntegrationTest.Initializer.class, classes = {AbtractIntegrationTest.LocalRibbonClientConfiguration.class })
@SpringBootTest(properties = { "app.config-service.base-path=","app.fraud-service.base-path=http://localhost:${wiremock.server.port}/evaluate"}, webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureWireMock(port = 0, stubs = "classpath*:/wiremock/**/mappings/**/*.json", files = "classpath:/wiremock")
@Testcontainers
public class AbtractIntegrationTest {
- Define which Spring @Configuration to load.
- Initializer class set up a Postgres container.
- LocalRibbonClientConfiguration class add wiremock port server for finding local endpoints.
- This annotation allow us to create the ApplicationContext used in integration tests via SpringApplication.
- we override the external services base path for using
WireMock
endpoints.
- Annotation to start a mock web server with our stubs and mapping definitions.
- Clone this repository
git clone https://github.com/guedim/spring-projects.git
- Move to the directory
wiremock
cd spring-projects/wiremock
- For running integration test (using
WireMock
andTestContainers
with aPostgres
database) execute next command:
mvn verify