Efficient Unit Testing with Testcontainers and Docker...

Efficient Unit Testing with Testcontainers and Docker...

Hello Everyone

Discover how to boost your testing efficiency and reliability by using Testcontainers with Docker. The Mad Scientist will provides a step-by-step tutorial on setting up Testcontainers for Java applications, ensuring your unit tests run against real databases and closely mimic production environments.

Below, I'll provide examples using Java and the Testcontainers library to test a simple application that interacts with a PostgreSQL database:


Prerequisites

  • Java Development Kit (JDK) installed
  • Docker installed and running
  • Maven or Gradle for dependency management
  • IDE (e.g., IntelliJ IDEA, Eclipse) for coding

Step 1: Setting Up the Project

Create a new Maven project and add the following dependencies in your pom.xml:

xml

<dependencies>
    <!-- JUnit 5 dependency -->
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.7.1</version>
        <scope>test</scope>
    </dependency>

    <!-- Testcontainers dependency -->
    <dependency>
        <groupId>org.testcontainers</groupId>
        <artifactId>testcontainers</artifactId>
        <version>1.15.1</version>
        <scope>test</scope>
    </dependency>

    <!-- PostgreSQL Testcontainers module -->
    <dependency>
        <groupId>org.testcontainers</groupId>
        <artifactId>postgresql</artifactId>
        <version>1.15.1</version>
        <scope>test</scope>
    </dependency>

    <!-- PostgreSQL JDBC driver -->
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>42.2.18</version>
    </dependency>
</dependencies>
        


Step 2: Writing the Application Code

Create a simple DAO (Data Access Object) for interacting with the PostgreSQL database. For example, let's create a UserDao class:

java

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class UserDao {

    private final Connection connection;

    public UserDao(Connection connection) {
        this.connection = connection;
    }

    public void createTable() throws SQLException {
        String sql = "CREATE TABLE users (id SERIAL PRIMARY KEY, name VARCHAR(100) NOT NULL)";
        try (PreparedStatement stmt = connection.prepareStatement(sql)) {
            stmt.execute();
        }
    }

    public void addUser(String name) throws SQLException {
        String sql = "INSERT INTO users (name) VALUES (?)";
        try (PreparedStatement stmt = connection.prepareStatement(sql)) {
            stmt.setString(1, name);
            stmt.executeUpdate();
        }
    }

    public List<String> getUsers() throws SQLException {
        String sql = "SELECT name FROM users";
        List<String> users = new ArrayList<>();
        try (PreparedStatement stmt = connection.prepareStatement(sql);
             ResultSet rs = stmt.executeQuery()) {
            while (rs.next()) {
                users.add(rs.getString("name"));
            }
        }
        return users;
    }
}
        


Step 3: Writing the Unit Test with Testcontainers

Create a test class using JUnit 5 and Testcontainers to verify the functionality of UserDao:

java

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;

@Testcontainers
public class UserDaoTest {

    @Container
    public static PostgreSQLContainer<?> postgresContainer = new PostgreSQLContainer<>("postgres:13")
            .withDatabaseName("testdb")
            .withUsername("test")
            .withPassword("test");

    private static Connection connection;
    private static UserDao userDao;

    @BeforeAll
    public static void setUp() throws SQLException {
        postgresContainer.start();
        connection = DriverManager.getConnection(postgresContainer.getJdbcUrl(), postgresContainer.getUsername(), postgresContainer.getPassword());
        userDao = new UserDao(connection);
        userDao.createTable();
    }

    @AfterAll
    public static void tearDown() throws SQLException {
        connection.close();
        postgresContainer.stop();
    }

    @Test
    public void testAddAndGetUsers() throws SQLException {
        userDao.addUser("Alice");
        userDao.addUser("Bob");

        List<String> users = userDao.getUsers();

        assertEquals(2, users.size());
        assertEquals("Alice", users.get(0));
        assertEquals("Bob", users.get(1));
    }
}
        


Step-by-Step Explanation

1. Dependencies: We include dependencies for JUnit 5, Testcontainers, and PostgreSQL.


2. Application Code:UserDao is a simple DAO class for interacting with a PostgreSQL database. It includes methods to create a table, add a user, and retrieve users.


3. Unit Test:

  • Testcontainers Setup: We use the @Testcontainers annotation and define a PostgreSQLContainer with the @Container annotation.
  • Database Connection: In the setUp method, we start the PostgreSQL container and establish a connection to the database.
  • Tear Down: In the tearDown method, we close the database connection and stop the container.
  • Test Method: The testAddAndGetUsers method tests adding users to the database and retrieving them. We use JUnit's assertEquals to verify the results.


Running the Tests

Run the test class (UserDaoTest) using your IDE or from the command line with Maven:

sh

mvn test        

This setup ensures that your unit tests run against a real PostgreSQL instance provided by Docker, improving the reliability and accuracy of your tests.


Using Testcontainers, you can easily spin up and tear down containers for your tests, ensuring a clean environment every time and avoiding issues related to different development environments


Fidel V (the Mad Scientist)

Project Engineer || Solution Architect

Security ? AI ? Systems ? Cloud ? Software

.

.

.

.

.

.

?? The #Mad_Scientist "Fidel V. || Technology Innovator & Visionary ??

#AI / #AI_mindmap / #AI_ecosystem / #ai_model / #Space / #Technology / #Energy / #Manufacturing / #stem / #Docker / #Kubernetes / #Llama3 / #integration / #cloud / #Systems / #blockchain / #Automation / #LinkedIn / #genai / #gen_ai / #LLM / #ML / #analytics / #automotive / #aviation / #SecuringAI / #python / #machine_learning / #machinelearning / #deeplearning / #artificialintelligence / #businessintelligence / #cloud / #Mobileapplications / #SEO / #Website / #Education / #engineering / #management / #security / #android / #marketingdigital / #entrepreneur / #linkedin / #lockdown / #energy / #startup / #retail / #fintech / #tecnologia / #programing / #future / #creativity / #innovation / #data / #bigdata / #datamining / #strategies / #DataModel / #cybersecurity / #itsecurity / #facebook / #accenture / #twitter / #ibm / #dell / #intel / #emc2 / #spark / #salesforce / #Databrick / #snowflake / #SAP / #linux / #memory / #ubuntu / #apps / #software / #io / #pipeline / #florida / #tampatech / #Georgia / #atlanta / #north_carolina / #south_carolina / #personalbranding / #Jobposting / #HR / #Recruitment / #Recruiting / #Hiring / #Entrepreneurship / #moon2mars / #nasa / #Aerospace / #spacex / #mars / #orbit / #AWS / #oracle / #microsoft / #GCP / #Azure / #ERP / #spark / #walmart / #smallbusiness


要查看或添加评论,请登录

Fidel .V的更多文章

社区洞察

其他会员也浏览了