Refactor testcontainers service connections

Update restcontainers service connections support so that
technology specific `@ServiceConnector` annotations are not longer
required.

A single `@ServiceConnector` annotation can now be used to create
all `ConnectionDetail` beans.

Closes gh-35017
This commit is contained in:
Phillip Webb
2023-04-12 22:36:59 -07:00
parent 11dac5b5b7
commit 81a972af8d
78 changed files with 1297 additions and 903 deletions

View File

@@ -18,12 +18,12 @@ For additional details on Spring Security's testing support, see Spring Security
[[howto.testing.testcontainers]]
=== Use Testcontainers for Integration Testing
The https://www.testcontainers.org/[Testcontainers] library provides a way to manage services running inside Docker containers.
It integrates with JUnit, allowing you to write a test class that can start up a container before any of the tests run.
Testcontainers is especially useful for writing integration tests that talk to a real backend service such as MySQL, MongoDB, Cassandra and others.
Testcontainers can be used in a Spring Boot test as follows:
include::code:vanilla/MyIntegrationTests[]
@@ -32,6 +32,7 @@ This will start up a docker container running Neo4j (if Docker is running locall
In most cases, you will need to configure the application to connect to the service running in the container.
[[howto.testing.testcontainers.service-connections]]
==== Service Connections
A service connection is a connection to any remote service.
@@ -42,24 +43,69 @@ When using Testcontainers, connection details can be automatically created for a
include::code:MyIntegrationTests[]
Thanks to `@Neo4jServiceConnection`, the above configuration allows Neo4j-related beans in the application to communicate with Neo4j running inside the Testcontainers-managed Docker container.
Thanks to `@ServiceConnection`, the above configuration allows Neo4j-related beans in the application to communicate with Neo4j running inside the Testcontainers-managed Docker container.
This is done by automatically defining a `Neo4jConnectionDetails` bean which is then used by the Neo4j auto-configuration, overriding any connection-related configuration properties.
The following service connection annotations are provided by `spring-boot-test-autoconfigure`:
Service connection annotations are processed by `ContainerConnectionDetailsFactory` classes registered with `spring.factories`.
A `ContainerConnectionDetailsFactory` can create a `ConnectionDetails` bean based on a specific `Container` subclass, or the Docker image name.
- `@CassandraServiceConnection`
- `@CouchbaseServiceConnection`
- `@ElasticsearchServiceConnection`
- `@InfluxDbServiceConnection`
- `@JdbcServiceConnection`
- `@KafkaServiceConnection`
- `@MongoServiceConnection`
- `@Neo4jServiceConnection`
- `@R2dbcServiceConnection`
- `@RabbitServiceConnection`
- `@RedisServiceConnection`
The following service connection factories are provided in the `spring-boot-testcontainers` jar:
As with the earlier `@Neo4jConnectionDetails` example, each can be used on a container field. Doing so will automatically configure the application to connect to the service running in the container.
|===
| Connection Details | Matched on
| `CassandraConnectionDetails`
| Containers of type `CassandraContainer`
| `CouchbaseConnectionDetails`
| Containers of type `CouchbaseContainer`
| `ElasticsearchConnectionDetails`
| Containers of type `ElasticsearchContainer`
| `FlywayConnectionDetails`
| Containers of type `JdbcDatabaseContainer`
| `InfluxDbConnectionDetails`
| Containers of type `InfluxDBContainer`
| `JdbcConnectionDetails`
| Containers of type `JdbcDatabaseContainer`
| `KafkaConnectionDetails`
| Containers of type `KafkaContainer`
| `LiquibaseConnectionDetails`
| Containers of type `JdbcDatabaseContainer`
| `MongoConnectionDetails`
| Containers of type `MongoDBContainer`
| `Neo4jConnectionDetails`
| Containers of type `Neo4jContainer`
| `R2dbcConnectionDetails`
| Containers of type `MariaDBContainer`, `MSSQLServerContainer`, `MySQLContainer` or `PostgreSQLContainer`
| `RabbitConnectionDetails`
| Containers of type `RabbitMQContainer`
| `RedisConnectionDetails`
| Containers named "redis"
|===
[TIP]
====
By default all applicable connection details beans will be created for a given `Container`.
For example, a `PostgreSQLContainer` will create both `JdbcConnectionDetails` and `R2dbcConnectionDetails`.
If you want to create only a subset of the applicable types, you can use the `type` attribute of `@ServiceConnection`.
====
By default `Container.getDockerImageName()` is used to obtain the name used to find connection details.
If you are using a custom docker image, you can use the `name` attribute of `@ServiceConnection` to override it.
For example, if you have a `GenericContainer` using a Docker image of `registry.mycompany.com/mirror/myredis`, you'd use `@ServiceConnection(name="redis")` to ensure `RedisConnectionDetails` are created.