Laravel 8数据库缓存测试需区分缓存逻辑与数据库协同行为:前者用Unit测试验证Cache门面操作,后者用Feature测试结合内存SQLite和RefreshDatabase验证查询缓存命中与失效,并可通过切换array驱动或Cache::spy精准校验键生成与清除逻辑。

Laravel 8 中测试数据库缓存,核心是区分「缓存逻辑本身」和「缓存与数据库协同行为」——前者测 Cache 门面操作是否正确,后者测模型/查询结果是否按预期被缓存、命中或失效。两者都需隔离真实环境,避免污染开发库或依赖外部服务。
缓存读写基础测试(不依赖数据库)
直接使用 Cache::put()、Cache::get() 等门面方法时,无需数据库连接,适合放在 tests/Unit/ 下:
- 测试类继承
PHPUnit\Framework\TestCase即可,不用 Laravel 的TestCase(除非你要用RefreshDatabase等 Trait) - 写法示例:
Cache::put('user_count', 123, 60);<br>$this->assertEquals(123, Cache::get('user_count')); - 验证过期:用
Cache::shouldReceive('has')->with('key')->andReturn(false)(Mockery)或直接设短有效期后 sleep + 断言失败
测试 Eloquent 查询缓存(需数据库配合)
这是更常见的场景,比如在模型中调用 Cache::remember() 缓存查询结果。它既涉及数据库查询,又涉及缓存操作,建议放 tests/Feature/ 并启用内存数据库:
- 确保
phpunit.xml中DB_CONNECTION=sqlite且DB_DATABASE=:memory: - 用
RefreshDatabaseTrait 清理每次测试后的状态 - 先执行一次查询并缓存:
$users = User::remember(300)->get(); - 清空查询日志:
DB::flushQueryLog();,再查一次,断言DB::getQueryLog()为空 → 表明走缓存 - 手动删缓存:
Cache::forget('users'),再查,断言查询日志非空
模拟缓存驱动避免真实存储
若不想依赖 Redis 或文件缓存驱动(尤其 CI 环境无 Redis),可在测试中强制切换为数组驱动:
- 在
setUp()中添加:Cache::setDefaultDriver('array'); - 或在
phpunit.xml里覆盖环境变量:<env name="CACHE_DRIVER" value="array"/> - 这样所有
Cache::*操作都在内存完成,速度快、可预测、无需额外服务
验证缓存键生成与失效逻辑
业务中常按用户 ID、分页参数等动态生成缓存键,或在数据变更时清除相关缓存。测试重点不是“有没有缓存”,而是“键对不对”“清得准不准”:
- 不要只测
Cache::get('users:all'),要测User::cacheKeyForAll()方法返回值是否符合预期 - 更新用户后,检查
Cache::has('user_5')是否为false(如果逻辑是更新即清) - 用
Cache::spy()(Laravel 9+)或 Mockery 拦截forget()调用,断言参数是否匹配目标键


















