Repository Testing :: TestContainer - up1/course-springboot-2024 GitHub Wiki
Repository testing with TestContainer
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-testcontainers</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>junit-jupiter</artifactId>
<version>1.20.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>1.20.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>mysql</artifactId>
<version>1.20.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.3.0</version>
<scope>runtime</scope>
</dependency>
File src/main/resources/application.properties
spring.sql.init.mode=always
spring.jpa.hibernate.ddl-auto=none
spring.datasource.hikari.maxLifetime=600000
spring.datasource.initialization-mode=always
# In MySQL 8, serverTimezone=UTC is deprecated in favor of connectionTimeZone
spring.datasource.url=jdbc:mysql://localhost:3306/test?connectionTimeZone=UTC
# The Hibernate dialect doesn't need to be explicitly specified anymore in Hibernate 6
# spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQLDialect
spring.datasource.username=root
spring.datasource.password=secret
File src/tests/resources/application.properties
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.sql.init.mode=never
CREATE TABLE IF NOT EXISTS my_user (
id int(10) PRIMARY KEY,
first_name VARCHAR(256) NOT NULL,
last_name VARCHAR(256) NOT NULL,
age int(10),
CONSTRAINT uc_user_first_last_name UNIQUE(first_name, last_name),
INDEX idx_user_id (id)
) engine=InnoDB;
import java.util.Optional;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.testcontainers.containers.MySQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Testcontainers
class UserRepositoryMySQLTest {
@Container
@ServiceConnection
static MySQLContainer<?> mySQLContainer = new MySQLContainer<>("mysql");
@DynamicPropertySource
static void mysqlProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.url", () -> mySQLContainer.getJdbcUrl());
registry.add("spring.datasource.driverClassName", () -> mySQLContainer.getDriverClassName());
registry.add("spring.datasource.username", () -> mySQLContainer.getUsername());
registry.add("spring.datasource.password", () -> mySQLContainer.getPassword());
registry.add("spring.sql.init.mode", () -> "always");
}
@Autowired
private UserRepository userRepository;
@Test
public void case01() {
// Arrange
MyUser dummy = new MyUser();
dummy.setId(1L);
dummy.setFirstName("Somkiat");
dummy.setLastName("Pui");
userRepository.saveAndFlush(dummy);
// Act
Optional<MyUser> result = userRepository.findById(1L);
// Assert
assertEquals(1, result.get().getId());
assertEquals("Somkiat", result.get().getFirstName());
}
}
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-docker-compose</artifactId>
<optional>true</optional>
</dependency>
Create file docker-compose.yml
services:
mysql:
image: mysql
environment:
MYSQL_ROOT_PASSWORD: secret
MYSQL_DATABASE: test
MYSQL_USER: user
MYSQL_PASSWORD: password
ports:
- "3306:3306"