Laravel测试中RefreshDatabase trait失效报错问题求解
你的测试数据库配置环节没有任何错误,报错和数据库配置无关,是Laravel升级过程中组件版本对PHP7.4兼容不到位导致的。
RefreshDatabase trait内部调用migrate:fresh Artisan命令时,传参格式不符合当前安装的Symfony Console组件的参数解析规则:组件遍历输入参数列表时,把索引数组的整数键当成了参数名键处理,执行$key[0]判断参数是不是短选项(-开头)时,因为$key是整数类型,触发“访问整数类型值的数组偏移量”错误。
高版本Symfony组件用str_starts_with替换了原有的字符串偏移判断,但该函数仅支持PHP8及以上版本,和你当前的PHP7.4运行环境不兼容。
三种方案任选其一即可:
方案1:重写适配版本的RefreshDatabase trait(推荐,无需调整依赖版本)
不要直接引用框架自带的RefreshDatabase,在测试目录下重写迁移调用逻辑,修正传参格式,避免参数解析错误:- 新建文件
tests/RefreshDatabase.php,写入以下代码:
<?php namespace Tests; use Illuminate\Foundation\Testing\RefreshDatabase as BaseTrait; trait RefreshDatabase { use BaseTrait; protected function migrateFresh(array $options = []) { $this->artisan('migrate:fresh', [ '--database' => config('database.default'), '--drop-views' => false, ])->assertExitCode(0); } }- 测试类中引入
Tests\RefreshDatabase替换原有的框架trait即可。
- 新建文件
方案2:锁定兼容PHP7.4的Symfony Console版本
执行composer命令将symfony/console锁定到5.4.x系列(该版本为兼容PHP7.4的最终稳定版,已修复整数键访问的bug,且不依赖PHP8专属函数):composer require symfony/console:5.4.* --with-all-dependencies命令执行完成后清除配置缓存,重新运行测试即可。
方案3:回退使用Laravel原生兼容的迁移trait
如果不需要migrate:fresh的全量删表重建逻辑,可以直接替换为Laravel 5.5原生支持的DatabaseMigrationstrait,该trait每次测试执行后回滚迁移,不会触发migrate:fresh相关的参数解析错误,只需将测试类引入的trait替换为Illuminate\Foundation\Testing\DatabaseMigrations即可。
内容的提问来源于stack exchange,提问作者Cynical

