升级Laravel 6后关联模型相关单元测试出现随机不稳定问题
Laravel 5.8升级6.0后关联模型单元测试不稳定修复方案
问题定位
此类无需修改代码、同用例随机成功/失败的场景,本质是测试环境数据隔离失效或Laravel版本变更带来的关联逻辑兼容问题,可按以下步骤逐一排查修复:
- 确认测试类事务隔离配置正确
Laravel 6对RefreshDatabasetrait底层逻辑做了调整,若测试类混用旧版DatabaseMigrationstrait、或是同时开启事务隔离+进程隔离,会导致上一条测试的残留数据影响下一条测试的外键校验。请确保所有涉及数据库操作的测试类仅引入RefreshDatabasetrait,关闭phpunit.xml中的processIsolation配置项。 - 修正关联字段赋值写法
你当前手动赋值的写法不符合Laravel 6的模型规则:如果Book模型的作者外键默认命名为author_id,直接传'author' => $author->getKey()会触发字段不存在的隐性报错,而工厂随机生成的外键可能合法也可能非法,最终表现为测试随机失败。正确写法如下:
$author = factory(Author::class)->create(); $book = factory(Book::class)->create([ 'title' => 'test', 'author_id' => $author->getKey() ]); // 也可直接传关联实例,由框架自动处理外键赋值: // $book = factory(Book::class)->create(['title' => 'test', 'author' => $author]);
- 排查工厂定义的隐性随机逻辑
检查BookFactory定义中是否有未覆盖的外键随机生成逻辑,比如默认写了'author_id' => factory(Author::class),如果调用create方法时未主动覆盖该字段,工厂会随机生成关联数据,可能出现关联查询不到的场景。 - 关闭测试环境懒加载异常提醒
Laravel 6新增了非生产环境禁用懒加载的配置项,若你在全局配置中开启了Model::preventLazyLoading(! app()->isProduction()),测试代码中隐式调用懒加载关联的逻辑会随机抛出异常。可在测试基类的setUp方法中临时关闭该配置验证:
protected function setUp(): void { parent::setUp(); \Illuminate\Database\Eloquent\Model::preventLazyLoading(false); }
- 确认测试数据库配置正确
确保phpunit.xml中配置的是独立的测试数据库,不要和开发环境共用数据库,优先使用sqlite内存数据库提升性能同时避免数据残留。
内容的提问来源于stack exchange,提问作者Hevyweb
相关产品推荐
相关产品推荐

