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:
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.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?
- 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
- "app.jdbc.url" will be changed exactly
n
times, wheren
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.