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