Search code examples
spring-bootdockerdocker-composecontainerstestcontainers

Can you use Testcontainers to manage service dependencies, like a database, during local development?


Testcontainers can manage dockerized service dependencies, like a database, Kafka, Elasticsearch, and so on for integration testing.

Can I configure my Spring Boot application to manage these service dependencies during local development?

For example, my Spring Boot application needs a MySQL database. I would like to integrate it with Testcontainers to provide a Docker container with MySQL not only during the tests execution, but at application startup during local development too.


Solution

  • Testcontainers provides an API to manage applications and services in Docker containers. It's incredibly useful for integration testing, where having a programmatically configured, isolated, repeatable environments is an essential requirement for trustworthy tests. Because of that Testcontainers has integrations with the frameworks like Spring and Quarkus, and tes frameworks like JUnit, Spock, etc to automatically tie the lifecycle of your containerized dependencies to the lifecycle of the tests.

    However, Testcontainers API is generic and doesn't have to run during the tests. For example, Quarkus has a feature called Dev Services which automatically creates a container for your database (or other service dependencies, for example Kafka, Redis, etc) when your application tries to access the database, but the configuration is not present.

    You can think about it like this, if you have the data access repository classes initialized and wired, but no datasource.url in the config -- it'll spin up the database using testcontainers and configure the app to use it (just like it would happen during tests, but instead used for local development).

    Spring Boot doesn't have an automated feature like that currently, there's an open issue to investigate these local development setups with Testcontainers.

    If you're open to manually add a feature for your particular application, you can look at the prototype linked from that issue here: https://github.com/joshlong/testcontainers-auto-services-prototype

    It's a bit more involved because it integrates with the Spring DevTools, but here are the essential parts that need to be taken care of:

    • Check that you need to use the database (in your application it can be a given).
    • Verify the configuration to use the database is absent (if the database is already configured you don't need to spin up a new one)
    • Create a container using Testcontainers API, either using an appropriate module or the GenericContainer with any Docker image.
    • Provide the configuration back to the application. For the database that would be the jdbcUrl, username, password, database name, r2dbcUrl and any other relevant properties.

    You can take a look at the video with Josh Long where this concept was tried: https://www.youtube.com/watch?v=1PUshxvTbAc&t=2450s

    It would also work in the production environments, but the usefulness of the ephemeral Databases, might be limited.