{"id":18751850,"url":"https://github.com/hendisantika/spring-boot-testcontainer-mysql","last_synced_at":"2025-04-13T00:13:37.902Z","repository":{"id":67605553,"uuid":"529053897","full_name":"hendisantika/spring-boot-testcontainer-mysql","owner":"hendisantika","description":"Sample Spring Boot application that uses MySQL to perform integration tests by using TestContainer.","archived":false,"fork":false,"pushed_at":"2025-03-22T20:37:08.000Z","size":174,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-13T00:13:33.989Z","etag":null,"topics":["cloud","integration-testing","testcontainers"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hendisantika.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-08-25T23:52:34.000Z","updated_at":"2025-03-22T20:37:06.000Z","dependencies_parsed_at":"2023-02-23T13:00:10.848Z","dependency_job_id":"b622c7eb-a213-4db0-be3e-fe38d0130530","html_url":"https://github.com/hendisantika/spring-boot-testcontainer-mysql","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hendisantika%2Fspring-boot-testcontainer-mysql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hendisantika%2Fspring-boot-testcontainer-mysql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hendisantika%2Fspring-boot-testcontainer-mysql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hendisantika%2Fspring-boot-testcontainer-mysql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hendisantika","download_url":"https://codeload.github.com/hendisantika/spring-boot-testcontainer-mysql/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248647276,"owners_count":21139086,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cloud","integration-testing","testcontainers"],"created_at":"2024-11-07T17:17:32.659Z","updated_at":"2025-04-13T00:13:37.876Z","avatar_url":"https://github.com/hendisantika.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Spring Boot: MySQL Container Integration\n\nAvoid running different databases between integration tests and production.\n\n![Maven Build](https://github.com/hendisantika/spring-boot-testcontainer-mysql/workflows/Maven%20Build/badge.svg?branch=main)\n\n## Background\n\nIn general, we tend to use [H2][2] to perform integration tests within the application. However there are scenarios\nwhere H2 may not give the same outcome as our actual database, such as MySQL. Such scenario is when you have a table\ncolumn called _rank_ or _order_.\n\nBoth names are allowed with H2 database but not with MySQL as those are reserved keywords. Therefore it is best to\nuse the same database, in production environment, for our integration tests.\n\nIn this guide, we will implement [MySQL Container][3], from [TestContainers][1], with [Spring Boot][4].\n\n## Dependencies\n\nFull dependencies can be found in [pom.xml][5].\n\n### Database\n\n- `spring-boot-starter-data-jpa`\n- `spring-boot-starter-data-rest`\n- `mysql-connector-java`\n\n### Integration tests\n\n- `junit-jupiter` from TestContainers\n- `mysql` from TestContainers\n\n## Implementation\n\n### Entity Class\n\nGiven we have a class called [Book][6] along with its repository class, [BookRepository][7].\n\n```java\n@Data\n@Entity\npublic class Book {\n\n    @Id\n    @GeneratedValue\n    private Long id;\n\n    @Embedded\n    private Author author;\n\n    private String title;\n\n}\n```\n\n```java\npublic interface BookRepository extends JpaRepository\u003cBook, Long\u003e {\n}\n```\n\n### Test Implementation\n\nHere we will be utilizing MySQL module from TestContainers to perform integration tests. The following implementation\ncan be found in [BookRepositoryRestResourceTests][10]\n\n#### Enable TestContainers\n\n`org.testcontainers:junit-jupiter` dependency simplifies our implementation whereby the dependency will handle the  \nstart and stop of the container.\n\nWe will start by informing `@SpringBootTest` that we will be using `ContainerDatabaseDriver` as our driver class  \nalong with our JDBC URL\n\n```java\n@Testcontainers\n@SpringBootTest(\n        properties = {\n                \"spring.jpa.generate-ddl=true\",\n                \"spring.datasource.url=jdbc:tc:mysql:8:///test\n        }\n)\npublic class BookRepositoryRestResourceTests {\n\n}\n```\n\nWe will trigger a REST call to create a Book and given that there is a database running, the book should be created.\n\n```java\n@Testcontainers\n@SpringBootTest(\n        properties = {\n                \"spring.jpa.generate-ddl=true\",\n                \"spring.datasource.url=jdbc:tc:mysql:8:///test\n        },\n        webEnvironment = RANDOM_PORT\n)\npublic class BookRepositoryRestResourceTests {\n\n    @Autowired\n    private TestRestTemplate restTemplate;\n\n    @Test\n    @DisplayName(\"Entity will be created if datasource is available\")\n    void create() {\n        var author = author();\n\n        var book = book(author);\n\n        ResponseEntity\u003cBook\u003e response = restTemplate.postForEntity(\"/books\", book, Book.class);\n\n        assertThat(response.getStatusCode()).isEqualTo(CREATED);\n    }\n\n    private Author author() {\n        var author = new Author();\n\n        author.setName(\"Rudyard Kipling\");\n\n        return author;\n    }\n\n    private Book book(final Author author) {\n        var book = new Book();\n\n        book.setAuthor(author);\n        book.setTitle(\"The Jungle Book\");\n\n        return book;\n    }\n\n}\n```\n\nExecute the test and you will get HTTP `200` or `CREATED` returned. To be certain that our test did run with\nMySQL Container, we should see the following content in the logs:\n\n```shell script\nDEBUG 🐳 [mysql:8] - Starting container: mysql:8\n...\norg.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.MySQL8Dialect\n```\n\nThis is how the application informing us that it is using MySQL Container which lead to Spring Boot automatically\nconfigure our dialect to `MySQL8Dialect`.\n\n### Verify MySQL availability\n\nAnother option is to verify that our application will connect to MySQL by triggering a check against\n[Spring Boot Actuator Health][11] endpoint.\n\n```java\npublic class DatasourceHealthTests {\n\n    @Test\n    @DisplayName(\"Database status will be UP and Database name should be MySQL\")\n    void databaseIsAvailable() throws JsonProcessingException {\n        var response = restTemplate.getForEntity(\"/actuator/health\", String.class);\n\n        assertThat(response.getBody()).isNotNull();\n\n        JsonNode root = new ObjectMapper().readTree(response.getBody());\n        JsonNode dbComponentNode = root.get(\"components\").get(\"db\");\n\n        String dbStatus = dbComponentNode.get(\"status\").asText();\n        String dbName = dbComponentNode.get(\"details\").get(\"database\").asText();\n\n        assertThat(dbStatus).isEqualTo(\"UP\");\n        assertThat(dbName).isEqualTo(\"MySQL\");\n    }\n\n}\n```\n\nTest above verifies that there's a running MySQL database connected to the application. Full implementation can be\nfound in [DatasourceHealthTests][12].\n\n### Conclusion\n\nNow that we are running the same database as production environment, we can expect more accurate results from our\nintegration tests.\n\n[1]: https://www.testcontainers.org/\n\n[2]: https://www.h2database.com/html/main.html\n\n[3]: https://www.testcontainers.org/modules/databases/mysql/\n\n[4]: https://spring.io/projects/spring-boot\n\n[5]: pom.xml\n\n[6]: src/main/java/scratches/tc/domain/Book.java\n\n[7]: src/main/java/scratches/tc/domain/BookRepository.java\n\n[9]: https://docs.spring.io/spring-framework/docs/5.2.5.RELEASE/spring-framework-reference/testing.html#testcontext-ctx-management-dynamic-property-sources\n\n[10]: src/test/java/scratches/tc/domain/BookRepositoryRestResourceTests.java\n\n[11]: https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-features.html#production-ready-health\n\n[12]: src/test/java/scratches/tc/health/DatasourceHealthTests.java\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhendisantika%2Fspring-boot-testcontainer-mysql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhendisantika%2Fspring-boot-testcontainer-mysql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhendisantika%2Fspring-boot-testcontainer-mysql/lists"}