I have a sample project in which I experiment with different technologies.
I have the following setup:
How can I test the Repository layer with testcontainer-junit5?
Example of code I have now for CompanyRepositoryTest.java
:
@ExtendWith(SpringExtension.class)
@Testcontainers
public class CompanyRepositoryTest {
@Autowired
private CompanyRepository companyRepository;
@Container
public MySQLContainer mysqlContainer = new MySQLContainer()
.withDatabaseName("foo")
.withUsername("foo")
.withPassword("secret");;
@Test
public void whenFindByIdExecuted_thenNullReturned()
throws Exception {
assertEquals(companyRepository.findById(1L), Optional.ofNullable(null));
}
@Test
public void whenFindAllExecuted_thenEmptyListReturned() {
assertEquals(companyRepository.findAll(), new ArrayList<>());
}
}
When I add @SpringBootTest
, I need to set up all the context and have some Application load context issues?
The question is, can anyone demystify what @TestContainers
annotation does? What is the best practice or correct to use it while testing the Repository?
The JUnit 5 extension provided by the @Testcontainers
annotation scans for any containers declared with the @Container
annotation, and then starts and stops the those containers for your tests. Containers as static fields will be shared with all tests, and containers as instance fields will be started and stopped for every test.
If you are using Spring Boot, the easiest way to setup testcontainers for your tests is probably to provide properties in application-test.yml
. This will use the datasource JDBC URL to launch the testcontainers container. Refer to Testcontainers JDBC support for more information.
You can also test just the repository layer by using @DataJpaTest
instead of @SpringBootTest
:
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@ActiveProfiles("test")
class CompanyRepositoryTest { }
Your application-test.yml
file:
spring:
datasource:
url: jdbc:tc:mysql:8.0://hostname/databasename
driver-class-name: org.testcontainers.jdbc.ContainerDatabaseDriver
In some cases you might also want to use the @TestPropertySource
annotation instead:
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@TestPropertySource(
properties = {
"spring.datasource.url = jdbc:tc:mysql:8.0://hostname/test-database",
"spring.datasource.driver-class-name = org.testcontainers.jdbc.ContainerDatabaseDriver"
}
)
class CompanyRepositoryTest { }
Please note that the hostname
and test-database
are not actually used anywhere.