Bird
Raised Fist0
JUnittesting~10 mins

Test containers for database testing in JUnit - Test Execution Trace

Choose your learning style10 modes available
Test Overview

This test uses Testcontainers to start a temporary PostgreSQL database. It verifies that the application can connect and query the database correctly.

Test Code - JUnit 5
JUnit
import org.junit.jupiter.api.Test;
import org.testcontainers.containers.PostgreSQLContainer;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class PostgresContainerTest {

    @Test
    public void testDatabaseConnection() throws Exception {
        try (PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15.3")) {
            postgres.start();

            String jdbcUrl = postgres.getJdbcUrl();
            String username = postgres.getUsername();
            String password = postgres.getPassword();

            try (Connection conn = DriverManager.getConnection(jdbcUrl, username, password);
                 Statement stmt = conn.createStatement()) {

                stmt.execute("CREATE TABLE test_table(id INT PRIMARY KEY, name VARCHAR(255));");
                stmt.execute("INSERT INTO test_table VALUES (1, 'Test User');");

                ResultSet rs = stmt.executeQuery("SELECT name FROM test_table WHERE id = 1;");

                if (rs.next()) {
                    String name = rs.getString("name");
                    assertEquals("Test User", name);
                } else {
                    throw new AssertionError("No data found in test_table");
                }
            }
        }
    }
}
Execution Trace - 8 Steps
StepActionSystem StateAssertionResult
1Test startsJUnit test runner initializes the test method—PASS
2PostgreSQLContainer is created and startedA Docker container with PostgreSQL 15.3 is running and ready to accept connectionsContainer started successfullyPASS
3Connect to the PostgreSQL database using JDBC URL, username, and password from containerConnection to the temporary database is establishedConnection is not null and validPASS
4Execute SQL to create table 'test_table'Table 'test_table' created in the databaseTable creation executed without errorPASS
5Insert a row into 'test_table' with id=1 and name='Test User'One row inserted into 'test_table'Insert executed without errorPASS
6Query 'test_table' for name where id=1ResultSet contains one row with name='Test User'ResultSet has next rowPASS
7Assert that the retrieved name equals 'Test User'Assertion compares expected and actual valuesassertEquals("Test User", name)PASS
8Stop the PostgreSQL container and end the testDocker container is stopped and removed—PASS
Failure Scenario
Failing Condition: The test fails if the container does not start or the database connection cannot be established.
Execution Trace Quiz - 3 Questions
Test your understanding
What does the test verify after inserting data into the database?
AThat the table 'test_table' exists
BThat the database container is running
CThat the inserted name matches 'Test User'
DThat the connection URL is correct
Key Result
Using Testcontainers allows tests to run against a real database in a clean environment, improving reliability and avoiding dependencies on external databases.

Practice

(1/5)
1. What is the main advantage of using Testcontainers for database testing in JUnit?
easy
A. It provides a real database environment isolated for each test run.
B. It replaces the need for any database in tests with mocks.
C. It automatically writes test cases for database queries.
D. It speeds up tests by using in-memory databases only.

Solution

  1. Step 1: Understand what Testcontainers provide

    Testcontainers run real database instances inside containers, giving a fresh environment for each test.
  2. Step 2: Compare with other options

    Mocks or in-memory databases do not provide real database behavior, and Testcontainers do not auto-generate tests.
  3. Final Answer:

    It provides a real database environment isolated for each test run. -> Option A
  4. Quick Check:

    Real isolated DB environment = A [OK]
Hint: Testcontainers run real DBs isolated per test [OK]
Common Mistakes:
  • Thinking Testcontainers use mocks instead of real DBs
  • Confusing Testcontainers with in-memory databases
  • Believing Testcontainers auto-generate tests
2. Which of the following is the correct way to start a PostgreSQL container using Testcontainers in a JUnit test?
easy
A. PostgreSQLContainer postgres = new PostgreSQLContainer("latest:postgres").launch();
B. PostgreSQLContainer postgres = new PostgreSQLContainer("postgres:latest").run();
C. PostgreSQLContainer postgres = new PostgreSQLContainer("postgres").begin();
D. PostgreSQLContainer postgres = new PostgreSQLContainer<>("postgres:latest").start();

Solution

  1. Step 1: Check the correct constructor and method

    The correct constructor uses the image name string and the generic type, and the container is started with start().
  2. Step 2: Validate method names and image format

    Methods like run(), begin(), or launch() do not exist. The image name format must be "postgres:latest".
  3. Final Answer:

    PostgreSQLContainer postgres = new PostgreSQLContainer<>("postgres:latest").start(); -> Option D
  4. Quick Check:

    Use start() with correct image name [OK]
Hint: Use start() method with correct image name [OK]
Common Mistakes:
  • Using wrong method names like run(), begin(), or launch()
  • Incorrect image name format
  • Omitting generic type parameter
3. Given the following JUnit test snippet using Testcontainers, what will be the output of System.out.println(postgres.getJdbcUrl());?
PostgreSQLContainer postgres = new PostgreSQLContainer<>("postgres:13-alpine").start();
System.out.println(postgres.getJdbcUrl());
postgres.stop();
medium
A. The literal string "postgres:13-alpine"
B. An error because getJdbcUrl() is not available
C. A JDBC URL string like jdbc:postgresql://localhost:randomPort/test
D. Null, because the container is stopped immediately

Solution

  1. Step 1: Understand what getJdbcUrl() returns

    After starting, getJdbcUrl() returns the connection URL to the running container database.
  2. Step 2: Check container lifecycle and output

    The container is started before printing, so the URL is valid. The container stops after printing, so output is not null or error.
  3. Final Answer:

    A JDBC URL string like jdbc:postgresql://localhost:randomPort/test -> Option C
  4. Quick Check:

    getJdbcUrl() after start() returns valid URL [OK]
Hint: Call getJdbcUrl() only after container start() [OK]
Common Mistakes:
  • Calling getJdbcUrl() before start()
  • Expecting literal image name as URL
  • Assuming output is null after stop() immediately
4. Identify the error in this JUnit test using Testcontainers for MySQL:
@Test
void testDbConnection() {
  MySQLContainer mysql = new MySQLContainer("mysql:8.0");
  mysql.start();
  String url = mysql.getJdbcUrl();
  // Use url to connect
  mysql.stop();
  mysql.stop();
}
medium
A. Calling mysql.stop() twice causes an error.
B. Missing generic type parameter in MySQLContainer declaration.
C. Container must be started with run() instead of start().
D. The image name "mysql:8.0" is invalid.

Solution

  1. Step 1: Check MySQLContainer declaration

    MySQLContainer is a generic class and should be declared with a wildcard: MySQLContainer<?>.
  2. Step 2: Verify other parts

    Calling stop() twice is safe (idempotent). start() is correct method. Image name "mysql:8.0" is valid.
  3. Final Answer:

    Missing generic type parameter in MySQLContainer declaration. -> Option B
  4. Quick Check:

    Use MySQLContainer to avoid raw type warning [OK]
Hint: Always use generic type with Testcontainers classes [OK]
Common Mistakes:
  • Calling stop() multiple times causes error
  • Using run() instead of start()
  • Incorrect image name format
5. You want to write a JUnit test that uses a PostgreSQL Testcontainer and runs a SQL script to initialize the database before tests. Which approach correctly achieves this?
hard
A. Use withInitScript("init.sql") on the PostgreSQLContainer instance before starting it.
B. Manually connect after start() and run the SQL script using JDBC in each test method.
C. Include the SQL script inside the Docker image and use a custom image name.
D. Start the container, then copy the SQL file into the container using copyFileToContainer() and run it manually.

Solution

  1. Step 1: Identify Testcontainers feature for init scripts

    Testcontainers provide withInitScript() method to run SQL scripts automatically on container startup.
  2. Step 2: Compare alternatives

    Manual JDBC execution or copying files is more complex and error-prone. Custom images are possible but not necessary for simple init scripts.
  3. Final Answer:

    Use withInitScript("init.sql") on the PostgreSQLContainer instance before starting it. -> Option A
  4. Quick Check:

    Use withInitScript() for automatic DB initialization [OK]
Hint: Use withInitScript() to auto-run SQL on container start [OK]
Common Mistakes:
  • Running SQL manually in each test instead of init script
  • Modifying Docker images unnecessarily
  • Copying files manually instead of using built-in methods
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard