GitLab CI/CD执行SpringBootTest遇MySQL连接错误及配置方案
问题解答
1. 为什么@SpringBootTest会触发数据库连接?如何保留注解避免连接?
原因
@SpringBootTest默认会启动完整的Spring Boot应用上下文。如果你的项目中引入了spring-boot-starter-data-jpa、spring-boot-starter-jdbc这类数据库相关依赖,Spring Boot的自动配置机制会读取application.properties里的数据源配置,自动尝试创建数据库连接——哪怕你的测试用例根本不涉及数据库操作。
解决方法(保留@SpringBootTest的前提下避免连接)
有两种常用方案:
方案一:临时覆盖为内存数据库
在测试类上通过@SpringBootTest的properties属性,临时指定内存数据库(比如H2)替代真实MySQL配置:
@Slf4j @SpringBootTest(properties = { "spring.datasource.url=jdbc:h2:mem:testdb", "spring.datasource.driver-class-name=org.h2.Driver", "spring.jpa.hibernate.ddl-auto=create-drop" }) public class PersonControllerTest { @Test public void businessHealthCheckTest(){ log.info("Test started"); Assertions.assertThat(true).isTrue(); log.info("Test finished"); } }
方案二:禁用数据库自动配置
直接排除数据源、事务管理器等自动配置类,让Spring Boot启动时不加载数据库相关组件:
@Slf4j @SpringBootTest(exclude = { DataSourceAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, HibernateJpaAutoConfiguration.class }) public class PersonControllerTest { @Test public void businessHealthCheckTest(){ log.info("Test started"); Assertions.assertThat(true).isTrue(); log.info("Test finished"); } }
2. 当前场景下如何正确配置GitLab CI/CD的MySQL service?
如果你的测试确实需要连接MySQL(而非误触发),可按以下步骤调整配置:
问题分析
之前的配置未生效,大概率是因为MySQL容器还未完全启动,测试就开始执行,导致无法解析mysql主机名;另外需确保CI变量与应用配置完全匹配。
正确配置示例
调整gitlab-ci.yml
添加等待MySQL就绪的步骤,确保数据库服务可用后再执行测试:
run-test: image: gradle:7.2.0-jdk17 services: - name: mysql:latest alias: mysql # 主机别名需和application.properties中的地址一致(默认就是mysql,可省略) variables: MYSQL_DATABASE: "my_test_db" MYSQL_USER: "test_user" MYSQL_PASSWORD: "test_password" MYSQL_ROOT_PASSWORD: "root_password" MYSQL_CHARSET: "utf8mb4" MYSQL_COLLATION: "utf8mb4_unicode_ci" script: # 安装mysql客户端用于检测服务状态 - apt-get update && apt-get install -y --no-install-recommends mysql-client # 等待MySQL服务就绪(最多等待30秒,每2秒检测一次) - timeout 30 sh -c 'until mysql -h mysql -u "$MYSQL_USER" -p"$MYSQL_PASSWORD" -e "SELECT 1"; do sleep 2; done' # 执行测试 - gradle :business:test
确保application.properties配置匹配
保证应用的数据源配置与CI中定义的变量完全一致:
spring.datasource.url=jdbc:mysql://mysql:3306/my_test_db?useUnicode=yes&characterEncoding=UTF-8&createDatabaseIfNotExist=true spring.datasource.username=test_user spring.datasource.password=test_password # 根据测试需求设置DDL策略 spring.jpa.hibernate.ddl-auto=create-drop
额外提示
如果你的测试根本不需要数据库连接,完全不需要配置MySQL service,直接用第一个问题的方案禁用数据源配置即可,既节省CI资源又避免不必要的问题。
内容的提问来源于stack exchange,提问作者hhrzc
相关产品推荐
相关产品推荐

