How to reuse TestContainer ? (Junit 4)

1.8k views Asked by At

Hello everyone :) i have 3 questions :

  1. How Reuse TestContainer with Junit 4 ?
  2. How i can verify the amount of containers use during my test ?
  3. By default a new container started foreach @Test or for whole class ?

Thank you in advance for your answers


PostgresTestContainer.java

@ContextConfiguration(initializers = PostgresTestContainer.Initializer.class)
public abstract class PostgresTestContainer {


    @ClassRule
    public static PostgreSQLContainer postgresContainer = new PostgreSQLContainer(TCConfig.POSTGRESQL_VERSION.toString())
            .withDatabaseName(TCConfig.TC_DBNAME)
            .withUsername(TCConfig.TC_USERNAME)
            .withPassword(TCConfig.TC_PASSWORD);

    public static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

        private static String stringConnection = postgresContainer.getJdbcUrl();

        @Override
        public void initialize(ConfigurableApplicationContext applicationContext) {
            TestPropertyValues values = TestPropertyValues.of(
                    "spring.datasource.url=" + stringConnection,
                    "spring.datasource.username=" + TCConfig.TC_USERNAME,
                    "spring.datasource.password=" + TCConfig.TC_PASSWORD
            );
            values.applyTo(applicationContext);
        }
    }
}

PostgreSQL12Test.java


@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles("test")
public class PostgreSQL12_Test extends PostgresTestContainer {


    @Autowired
    private MemberService memberService;

    @Autowired
    private Flyway flyway;

    @Before
    public void initialize() {
        flyway.migrate();
    }

    @Test
    public void shoudRunPostgreSQLContainer() throws Exception {
        Connection connection = DriverManager.getConnection(postgresContainer.getJdbcUrl(), postgresContainer.getUsername(), postgresContainer.getPassword());
        ResultSet resultSet = connection.createStatement().executeQuery("SELECT 666");
        resultSet.next();
        int result = resultSet.getInt(1);
        assertThat(result).isEqualByComparingTo(666);

    }
}

VERSIONS

TestContainers - Postgresql : 1.13.0
Spring Boot : 2.0.0 ( Junit 4 )
Docker : 19.03.11
Os : 20.04.1 LTS (Focal Fossa)
2

There are 2 answers

2
Vitaly Chura On BEST ANSWER
  1. How Reuse TestContainer with Junit 4?

    It should already work the way you wrote your test. You have the container annotated with @ClassRule so it should only be loaded once.

  2. How i can verify the amount of containers use during my test?

    Put a breakpoint in your test method and run docker ps in a terminal.

  3. By default a new container started foreach @Test or for whole class?

    With @ClassRule it should be created for the class. You can just remove that annotation and then the lifecycle of the container will be managed by java itself (once if the field is static and for every test method if it's not)

0
Hussar On

To reuse Container for all test class just use static without @ClassRule or @Rule.


public class PostgresTestContainer {
    public static final PostgreSQLContainer POSTGRESQL_CONTAINER = new PostgreSQLContainer<>(DockerImageName.parse("postgres:9.6.12"))
            .withDatabaseName("db_name")
            .withUsername("db_user")
            .withPassword("db_pass");
    static {
        POSTGRE_SQL_CONTAINER.start();
    }
}