Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot TestContainers Mapped port can only be obtained after the container is started

I'm trying to add automated testing using the TestContainers library to my Spring Boot project

Here is my test class to test my jpa repository:

package com.ubm.mfi.repo;

import com.ubm.mfi.domain.MasterFileIndexRow;
import org.junit.ClassRule;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Testcontainers;

import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

@ExtendWith(SpringExtension.class)
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Testcontainers
@ContextConfiguration(initializers = { MasterFileIndexRowRepoTest.Initializer.class })
public class MasterFileIndexRowRepoTest {

    @ClassRule
    public static PostgreSQLContainer<?> postgreSQLContainer = new PostgreSQLContainer<>("postgres:latest");

    @Autowired
    private MasterFileIndexRowRepo masterFileIndexRowRepo;

    // write test cases here
    @Test
    public void whenFindAllRows_thenSizeIsGreaterThanZero() {
        // when
        List<MasterFileIndexRow> rows = masterFileIndexRowRepo.findAll();

        // then
        assertThat(rows.size())
                .isGreaterThan(0);
    }

    static class Initializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

        @Override
        public void initialize(ConfigurableApplicationContext configurableApplicationContext) {

            TestPropertyValues
                    .of("spring.datasource.url=" + postgreSQLContainer.getJdbcUrl(),
                            "spring.datasource.username=" + postgreSQLContainer.getUsername(),
                            "spring.datasource.password=" + postgreSQLContainer.getPassword())
                    .applyTo(configurableApplicationContext.getEnvironment());

        }

    }

}

Here are the dependencies in my build.gradle

testCompile "org.testcontainers:testcontainers:1.14.1"
testCompile "org.testcontainers:postgresql:1.14.1"

When running the Test I get this error: Caused by: java.lang.IllegalStateException: Mapped port can only be obtained after the container is started

From what I've seen, the container should start when starting the test, does anybody know what I'm missing?

like image 775
Will Harrison Avatar asked May 06 '20 00:05

Will Harrison


1 Answers

You are trying to use PostgresSQLContainer as JUnit ClassRule but your usage of @ExtendWith seems to indicate that you are using JUnit 5 / Jupiter which does not support JUnit 4 rules.

Use the JUnit 5 integration of Testcontainers instead: https://www.testcontainers.org/test_framework_integration/junit_5/

like image 193
Jens Schauder Avatar answered Nov 09 '22 14:11

Jens Schauder