mock 是 laravel 中专用于测试的辅助工具,仅应出现在 tests/ 目录下的 phpunit 测试中,用于模拟 http 请求、邮件、队列或第三方 api 等外部依赖,而非性能优化手段。

Mock 在 Laravel 中不是性能优化手段,而是测试辅助工具;真要“优化”,核心是别在生产环境误用、别让 Mock 干扰真实逻辑、别把测试数据塞进业务流程。
Mock 用在哪儿才合理
只该出现在 tests/ 目录下的 PHPUnit 测试里,比如模拟 HTTP 请求、队列推送、第三方 API 响应或数据库查询结果。它不解决 N+1、慢查询或内存溢出——那些得靠 with()、索引、缓存和分页。
- 控制器测试中 mock
HttpClient防止调用真实外部接口 - 模型测试中 mock
Mail::fake()或Notification::fake()避免发邮件 - 不要在
app/里写Mockery::mock()—— 这属于逻辑污染,不是“优化”
常见误用:用 Mock 替代真实优化
看到页面慢,第一反应不是加 DB::shouldReceive(),而是打开 Telescope 看 SQL 日志。Mock 掉一个慢查询只是掩盖问题,不是提速。
- 错误做法:在服务类里写
if (app()->environment('testing')) { return Mockery::mock(...) } - 正确做法:把慢查询抽成接口,测试时注入 mock 实现,生产时走真实 Eloquent
- Mock 返回空集合或固定数组,不代表你解决了
users表没索引的问题
Mock 性能本身也有坑
过度使用 Mockery 会拖慢测试执行速度,尤其在大量 shouldReceive() 链式调用时。Laravel 自带的 Mail::fake()、Queue::fake() 是轻量封装,优先用它们。
- 避免在每个测试方法里重复
Mockery::mock(SomeService::class),改用setUp()统一初始化 - 不用
Mockery::spy()去监听所有方法调用,除非真需要验证交互顺序 - Mock 的类如果本身有 heavy 初始化(比如读配置、连 Redis),记得用
makePartial()或直接 stub 构造函数
Mock 的边界很清晰:它是测试的“替身演员”,不是业务的“加速器”。真正影响线上性能的,永远是那几条没加索引的 WHERE、循环里漏掉的 with()、还有忘清的 bootstrap/cache/config.php。











