hyperf phpunit测试数据库连接失败,是因为测试进程未加载.env配置,导致db_host等环境变量为空;需在phpunit.xml中显式配置db_*环境变量并创建对应测试库。

Hyperf 的 PHPUnit 测试默认不连你配置的生产库,但也不会自动用测试库——它根本不会读 .env 里的 DB 配置,除非你显式告诉它。
为什么 phpunit 运行时数据库连接失败
Hyperf 启动时从 .env 加载配置,但 PHPUnit 测试进程是独立启动的,config/autoload/database.php 中的 env('DB_HOST') 在测试上下文中默认返回空或 fallback 值,而不是你期望的测试库地址。
- 常见错误现象:
PDOException: SQLSTATE[HY000] [1045] Access denied for user ''@'localhost'或连接超时,说明配置没生效 - 根本原因:PHPUnit 的 bootstrap(如
test/bootstrap.php)未触发 Hyperf 容器的完整环境加载流程,Dotenv没被重新解析,或解析顺序被覆盖 - 不是 .env 文件写错了,而是测试进程压根没读它——尤其当你用
php vendor/bin/phpunit直接运行时
在 phpunit.xml 中设置环境变量最稳
这是绕过所有自动加载歧义的硬控制方式,PHPUnit 原生支持,Hyperf 也能立即识别。
- 在
phpunit.xml的<php></php>节点下添加数据库相关环境变量:
<php><env name="DB_DRIVER" value="mysql"></env><env name="DB_HOST" value="127.0.0.1"></env><env name="DB_PORT" value="3306"></env><env name="DB_DATABASE" value="hyperf_test"></env><env name="DB_USERNAME" value="root"></env><env name="DB_PASSWORD" value=""></env><env name="DB_CHARSET" value="utf8mb4"></env></php>
- 必须提前手动创建
hyperf_test库:执行CREATE DATABASE hyperf_test CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - 不要依赖
APP_ENV=test来切换配置——Hyperf 的 config loader 不会因此重读 database.php,环境变量才是直接输入源 - 如果用了 Redis 或其他组件,同样需在
<php></php>中补全对应REDIS_*变量,否则可能因连接空值导致测试卡死
验证配置是否真正生效
别只看测试是否跑通,要确认连接用的是你指定的库,而非开发库或内存库。
- 在测试方法里临时加一行:
var_dump($this->getContainer()->get(\Hyperf\Database\Connection::class)->getPdo());,观察 host 和 dbname 字段 - 执行
php vendor/bin/phpunit --debug,看输出中是否打印出你设的DB_DATABASE=hyperf_test - 故意把
DB_DATABASE设成一个不存在的库名,应报错Unknown database 'xxx',而不是继续连上旧库——这才是配置起效的信号
最容易被忽略的是:Hyperf 的 Database 组件在测试中默认不开启连接池复用,每次 new Connection 都新建 PDO 实例。如果你在 setUp() 里反复调用查询又没 close,可能触发 MySQL 的 max_connections 限制,表现为随机性的连接拒绝。这种情况不会报错“配置不对”,而是在并发测试时突然失败。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











