Laravel 7测试时数据存入数据库却无法查看的原因咨询
问题描述
我使用Laravel 7框架,以下是我的配置:
phpunit.xml 配置
<server name="APP_ENV" value="testing"/> <server name="APP_IMAGES_PATH" value=""/> <server name="FILESYSTEM_DRIVER" value="tests"/> <server name="BCRYPT_ROUNDS" value="4"/> <server name="CACHE_DRIVER" value="array"/> <server name="LOG_CHANNEL" value="tests"/> <server name="DB_CONNECTION" value="test_db"/> <server name="DB_DATABASE" value="test_db"/> <server name="MAIL_MAILER" value="array"/> <server name="QUEUE_CONNECTION" value="redis"/> <server name="SESSION_DRIVER" value="array"/> <server name="TELESCOPE_ENABLED" value="false"/>
.env 配置
TEST_DB_CONNECTION=pgsql TEST_DB_HOST=127.0.0.1 TEST_DB_PORT=5432 TEST_DB_DATABASE=test_db TEST_DB_USERNAME=laravel TEST_DB_PASSWORD=password APP_ENV=testing
执行 php artisan test 时,运行以下代码:
$item = new OrderData; $item->integration = 'integration'; $item->external_reference = $this->xml_contents["order"]["order_id"]; $item->order_id = $this->xml_contents["order"]["order_id"]; $item->save();
我无法在数据库表 order_data 中看到已保存的数据,但紧接着执行的代码:
$orderData = OrderData::query()->where('external_reference', $orderId)->first();
却能获取到$orderData的数据。请问这是什么原因?
原因解析
这是Laravel测试的默认行为导致的:
- Laravel的测试类默认会引入
Illuminate\Foundation\Testing\RefreshDatabase特质(Laravel 7中也可能使用DatabaseTransactions特质),这个特质会在每个测试方法启动时开启数据库事务,测试方法执行完毕后自动回滚事务。 - 测试里调用
save()后,数据确实写入了数据库,但因为处于未提交的事务中,外部工具(比如数据库客户端)无法看到这些未提交的数据;而测试内紧接着的查询是在同一个事务里执行的,所以能读取到当前事务中的未提交数据。 - 测试结束后事务被自动回滚,数据库里不会留下任何测试产生的数据,这是框架为了保证每个测试都在干净的环境中运行,避免测试间互相干扰而设计的机制。
如果需要临时保留测试数据用于调试,可以:
- 暂时移除测试类中的
RefreshDatabase或DatabaseTransactions特质; - 或者在测试方法末尾手动调用
DB::commit()提交事务,但注意这会污染测试数据库,后续测试可能受影响,调试完成后记得恢复配置。
内容的提问来源于stack exchange,提问作者Fil
相关产品推荐
相关产品推荐

