AtomicJar Testcontainers

AtomicJar Testcontainers is a Java library that supports JUnit tests, providing lightweight, throwaway instances of common services that can run in a Docker container. Though initially targeted at the JVM ecosystem, it can be leveraged for other programming languages. Testcontainers is a great way to write integration tests for frameworks like Spring Boot, with a real database.

YugabyteDB supports for the YugabyteDB module in Testcontainers.

This document describes how to use Testcontainers to write integration tests for a Spring Boot application with YugabyteDB .

Prerequisites

To use Testcontainers, ensure that you have the following:

Build the Testcontainer project

Refer to the Spring Boot source from GitHub for your local setup. The source consists of a basic JPA-based web application with CRUD functionality.

You need to build the Testcontainer project using the following steps:

  1. Define the library dependency in the build file. Refer to the build.grade file for complete details.

    
    // version details for the BOM
    extra["testcontainersVersion"] = "1.17.6"
    
    // library
    dependencies {
        testImplementation("org.testcontainers:yugabytedb")
        testImplementation("org.testcontainers:junit-jupiter")
    }
    
    dependencyManagement {
    imports {
        mavenBom("org.testcontainers:testcontainers-bom:${property("testcontainersVersion")}")
    }
    }
    
  2. Initialize the YugabyteDB Testcontainer using the @Container annotation.

    @Container
    YugabyteDBYSQLContainer container = new YugabyteDBYSQLContainer("yugabytedb/yugabyte:2.16.0.0-b90").withDatabaseName("yugabyte").withUsername("yugabyte").withPassword("yugabyte").withReuse(true);
    

    Refer to AbstractTodoApplicationTest.java class file for the complete definition.

    The following snippet is required to populate the data source information:

    @DynamicPropertySource
    static void datasourceProps(final DynamicPropertyRegistry registry) {
      registry.add("spring.datasource.url", container::getJdbcUrl);
      registry.add("spring.datasource.username", container::getUsername);
      registry.add("spring.datasource.password", container::getPassword);
      registry.add("spring.datasource.driver-class-name", () -> "com.yugabyte.Driver");
    }
    

    An alternative to the preceding step is to define the tc JDBC URL in the application-test.yaml properties file.

    spring:
      datasource:
        url: jdbc:tc:yugabyte:2.14.4.0-b26:///yugabyte
        username: yugabyte
        password: yugabyte
    

Write the integration test classes

This example uses the standard way of writing integration test cases for the Spring Boot test framework with the following annotations:

  • @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.NONE) - This annotation loads the application context. The webEnvironment attribute is set to NONE because you do not want to start the embedded servlet container for your test. This property is mainly used when you want to test the service or repository layer.

  • @AutoConfigureTestDatabase(replace = NONE) - This annotation replaces any data source with the embedded H2 instance by default. So, you need to override this behavior by adding replace=Replace.NONE so that the application uses the real database through Testcontainers.

  • @Testcontainers - This annotation enables Testcontainers for the test class.

  • @ActiveProfiles(“test”) - This annotation activates the test application profile (application-test.[yaml|properties]). This profile configures the application to use the real database through Testcontainers.

  • @DataJpaTest- This annotation is for a JPA test focusing only on the repository components.

Refer to TodoApplicationServiceTest.java and TodoApplicationRepositoryTest.java to learn how to test the service layer and repository layer respectively.

Learn more