Test passed with @SpringBootTest and failed with @DataJpaTest
package com.example.demo;
import static org.assertj.core.api.Assertions.assertThat;
import javax.sql.DataSource;
import org.assertj.core.api.InstanceOfAssertFactories;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.springframework.context.annotation.Bean;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.containers.MySQLContainer;
import com.zaxxer.hikari.HikariDataSource;
@SpringBootTest // will pass
//@DataJpaTest // will fail
public class ApplicationTests {
@Autowired
private DataSource dataSource;
@Test
void test() {
assertThat(dataSource).isInstanceOf(HikariDataSource.class).extracting("jdbcUrl")
.asInstanceOf(InstanceOfAssertFactories.STRING).startsWith("jdbc:mysql://");
}
@TestConfiguration
static class Config {
@Bean
@ServiceConnection
GenericContainer<?> mysql() {
return new MySQLContainer<>("mysql:5.7");
}
}
}
plugins {
id 'java'
id 'org.springframework.boot' version '3.1.0-RC1'
id 'io.spring.dependency-management' version '1.1.0'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'
repositories {
mavenCentral()
maven {
url "https://repo.spring.io/milestone"
}
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.boot:spring-boot-testcontainers'
testImplementation 'org.testcontainers:junit-jupiter'
testImplementation 'org.testcontainers:mysql'
testRuntimeOnly 'com.h2database:h2'
testRuntimeOnly 'com.mysql:mysql-connector-j'
}
tasks.named('test') {
useJUnitPlatform()
}
Comment From: quaff
Here is workaround, add @Testcontainers and @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE), switch from @Bean to @Container like this:
package com.example.demo;
import static org.assertj.core.api.Assertions.assertThat;
import javax.sql.DataSource;
import org.assertj.core.api.InstanceOfAssertFactories;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.testcontainers.containers.MySQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import com.zaxxer.hikari.HikariDataSource;
@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Testcontainers
public class ApplicationTests {
@Container
@ServiceConnection
static MySQLContainer<?> container = new MySQLContainer<>("mysql:5.7");
@Autowired
private DataSource dataSource;
@Test
void test() {
assertThat(dataSource).isInstanceOf(HikariDataSource.class).extracting("jdbcUrl")
.asInstanceOf(InstanceOfAssertFactories.STRING).startsWith("jdbc:mysql://");
}
}
It's worthy to add notes like this to document, both section of DataJpaTest and Testcontainers.
Comment From: quaff
java @DataJpaTest @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) @Testcontainers public class ApplicationTests {
We could drop @AutoConfigureTestDatabase if https://github.com/spring-projects/spring-boot/pull/35125 is merged.
Comment From: quaff
Superseded by https://github.com/spring-projects/spring-boot/pull/35166