测试中配置不生效因config()函数与Config::set()状态不同步,需统一用Facade操作并调用reset()和app('config')->set([])重置双层缓存。

测试中修改配置项后不生效?先确认 config() 是 facade 还是函数调用
TP5.1 里 config() 既是函数也是 facade,但行为不同:直接调用 config('app.debug', true) 会写入运行时缓存,而 \think\facade\Config::set('app.debug', true) 才真正更新 facade 内部状态。测试中混用两者会导致断言失败——比如你改了 config(),但控制器里用的是 Config::get(),就取不到新值。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 统一用
\think\facade\Config操作,避免函数调用干扰 - 在
setUp()末尾加\think\facade\Config::reset(),防止上一个测试残留配置 - 若需临时覆盖,优先用
\think\facade\Config::set()而非全局函数
测试环境切换 config 文件却没加载?检查 config_path() 是否被硬编码
有些遗留代码在控制器里写死 include config_path() . '/extra/payment.php',这种路径拼接在测试时不会自动切到 tests/config/ 目录。PHPUnit 运行时 APP_PATH 和 CONFIG_PATH 仍指向生产路径,导致你改了测试配置文件,但代码压根没读它。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 不要在业务代码里手动 include 配置文件,改用
config('payment')让框架自动加载 - 如必须动态加载,把路径封装成可 mock 的方法,测试时用
$this->mock(...)->shouldReceive(...)拦截 - 在
phpunit.xml中通过<env name="APP_ENV" value="testing"></env>触发框架自动加载config/testing/下的覆盖配置
config 缓存未清导致测试间污染?别只 reset,还要 reload
\think\facade\Config::reset() 只清 facade 状态,不清理底层 think\Config 实例里的 $config 属性。如果测试 A 调用了 Config::load() 加载了自定义配置,测试 B 即使 reset() 了,仍可能读到旧数据——尤其当两个测试共用同一个 think\Config 单例时。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 在
setUp()里补一句app('config')->set([]),强制重置底层实例 - 对关键配置项(如
app.url、database.default),测试前显式Config::set(),不依赖默认值 - 避免在
AppServiceProvider或启动脚本中调用Config::load(),这类操作无法被单个测试隔离
为什么 config('database.connections.sqlite') 在测试里返回 null?SQLite 配置没注入进容器
TP5.1 默认数据库配置在 config/database.php,但测试时若用内存 SQLite,常有人只改 DB_CONNECTION 环境变量,却忘了确保 connections.sqlite 数组已存在。框架初始化时会尝试读这个键,缺失就报 undefined index 错误,而不是优雅 fallback。
实操建议:
立即学习“PHP免费学习笔记(深入)”;
- 在
tests/bootstrap.php中提前注册连接:Config::set('database.connections.sqlite', ['type' => 'sqlite', 'database' => ':memory:']) - 用
Config::has('database.connections.sqlite')断言配置存在,再执行数据库操作 - 不要依赖
.env文件覆盖——测试环境应显式声明,避免本地 .env 干扰 CI



















