I want to run spring integration tests with MySQLContainer in docker. I use volume for docker.sock, but have some troubles.
build.gradle:
plugins {
id 'java'
id 'org.springframework.boot' version '3.0.5'
id 'io.spring.dependency-management' version '1.1.0'
}
group = 'org.autovill'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-webflux', version: '3.0.5'
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-data-r2dbc', version: '3.0.5'
implementation 'org.springframework.boot:spring-boot-starter-security'
implementation group: 'org.flywaydb', name: 'flyway-core', version: '9.16.3'
implementation group: 'org.flywaydb', name: 'flyway-mysql', version: '9.16.3'
implementation group: 'io.asyncer', name: 'r2dbc-mysql', version: '1.0.0'
implementation group: 'com.mysql', name: 'mysql-connector-j', version: '8.0.32'
implementation group: 'io.jsonwebtoken', name: 'jjwt-api', version: '0.11.5'
runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-impl', version: '0.11.5'
runtimeOnly group: 'io.jsonwebtoken', name: 'jjwt-jackson', version: '0.11.5'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: '3.0.5'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.security:spring-security-test'
testImplementation group: 'io.projectreactor', name: 'reactor-test', version: '3.5.5'
testImplementation "org.testcontainers:testcontainers:1.18.0"
implementation platform('org.testcontainers:testcontainers-bom:1.18.0') //import bom
testImplementation('org.testcontainers:mysql') //no version specified
}
tasks.named('test') {
useJUnitPlatform()
}
test {
systemProperty 'spring.profiles.active', 'test'
}
I have such Dockerfile:
FROM gradle:7.6.1-jdk17-jammy as base
WORKDIR /app
COPY ./ ./
RUN gradle dependencies
FROM base as test
CMD ["gradle", "test"]
So, in tests I create MySQLContainer and set up properties.
@SpringBootTest
class AutovillApplicationStarterTest {
@ClassRule
public static MySQLContainer mysql = new MySQLContainer<>("mysql:8.0")
.withExposedPorts(3306, 3306)
.withEnv("MYSQL_ROOT_HOST", "%")
.withUsername("azamat")
.withPassword("123456")
.withDatabaseName("autovill")
.withEnv("MYSQL_HOST", "%");
static {
mysql.start();
System.out.println("MYSQL_HOST: " + mysql.getHost());
System.out.println("MYSQL JDBC URL: " + mysql.getJdbcUrl());
System.setProperty("spring.r2dbc.url", mysql.getJdbcUrl().replace("jdbc:", "r2dbc:"));
System.setProperty("spring.r2dbc.username", mysql.getUsername());
System.setProperty("spring.r2dbc.password", mysql.getPassword());
System.setProperty("spring.flyway.url", mysql.getJdbcUrl());
System.setProperty("spring.flyway.username", mysql.getUsername());
System.setProperty("spring.flyway.password", mysql.getPassword());
}
@Test
void contextLoads() {
}
}
It works well If i run it directly using gradle test. But If I run it via docker, there will be some troubles:
Building image:
docker build -t spring-test --target=test .
Runing container:
docker run \
--volume /var/run/docker.sock:/var/run/docker.sock \
-v $PWD:$PWD \
-w $PWD \
spring-test
Tests are not passed and I got such exception:
Caused by: java.lang.IllegalStateException: Could not connect to Ryuk at 172.17.0.1:49157
I tried to use -e TESTCONTAINERS_HOST_OVERRIDE=host.docker.internal parameter for docker run. Also, I created network and use it for MySQLContainer and docker run.