0

I have a general question about the relationship between integration tests in spring boot and testcontainers library. I will use example to illustrate the situation.

I am using testcontainers as described here: https://www.baeldung.com/spring-dynamicpropertysource#an-alternative-test-fixtures, I create the junit extension class

public class PostgreSQLExtension implements BeforeAllCallback, AfterAllCallback {

    private PostgreSQLContainer<?> postgres;

    @Override
    public void beforeAll(ExtensionContext context) {
        postgres = new PostgreSQLContainer<>("postgres:11")
          .withDatabaseName("prop")
          .withUsername("postgres")
          .withPassword("pass")
          .withExposedPorts(5432);

        postgres.start();
        String jdbcUrl = String.format("jdbc:postgresql://localhost:%d/prop", postgres.getFirstMappedPort());
        System.setProperty("app.jdbc.url", jdbcUrl);
    }

    @Override
    public void afterAll(ExtensionContext context) {
        // do nothing, Testcontainers handles container shutdown
    }
}

and later on, I am using it on my test classes

@SpringBootTest
@ExtendWith(PostgreSQLExtension.class)
public class SomeTest {
    @Autowired
    Foo foo;

    @Autowired
    Bar bar;
    // test code omitted for brevity
}

Lets say, that class Foo is using the jdbc url of database in the constructor:

@Component
class Foo {
    String jdbcUrl;
    public Foo(JdbcProperties jdbcProperties) {
        jdbcUrl = jdbcProperties.url();
    }

}

and here is the definition JdbcProperties:

@ConstructorBinding
@ConfigurationProperties(prefix = "app.jdbc")
public record JdbcProperties(String url) {
}

Two things are happening with such a setup:

  1. before any test class that is annotated with @ExtendWith(PostgreSQLExtension.class) there will be postgres container started, and more interestingly, system property "app.jdbc.url" will be overwritten.

  2. per spring documentation: https://docs.spring.io/spring-framework/docs/current/reference/html/testing.html#testing-ctx-management By default, once loaded, the configured ApplicationContext is reused for each test.

With the above facts, are the following statements true?

  1. every test, that will be run after the very first one, will use the same Foo object (created on test context creation), that was created just before first test was ran
  2. "app.jdbc.url" will be changed exactly n times, where n is the number of tests

If answer is yes, then how to assure, that foo object will be created with proper jdbc.url ?

Currently, my observations from real life project are making me think, that indeed those 2 facts are true and I don't know, how can I workaround the situation.

mdm
  • 13
  • 4

0 Answers0