正确命令是 composer require --dev mockery/mockery;需在 tearDown() 中调用 Mockery::close() 防止残留 mock 污染后续测试,且须确保 vendor/autoload.php 被正确加载。

Composer安装Mockery库的正确命令
直接运行 composer require --dev mockery/mockery 即可,--dev 表示仅在开发环境安装,不会打进生产包。Mockery 是纯 PHP 实现的模拟库,不依赖扩展,但要求 PHP ≥ 7.4(最新版 v1.6+),低于该版本需指定旧版,比如 composer require --dev mockery/mockery:^1.5。
安装后为什么 phpunit 还报错“Class 'Mockery' not found”
常见原因不是没装好,而是自动加载没触发或测试启动方式不对:
- 确认
vendor/autoload.php已在测试引导文件(如tests/bootstrap.php)中被require_once; - 如果用
phpunit命令直接运行单个测试文件(如phpunit tests/ExampleTest.php),它默认不加载项目级 bootstrap,需显式指定:phpunit --bootstrap vendor/autoload.php tests/ExampleTest.php; - 检查
composer.json的"autoload-dev"是否包含测试目录,否则Mockery类虽存在,但命名空间可能未注册进 Composer 自动加载器。
在 PHPUnit 测试中初始化 Mockery 的关键步骤
Mockery 默认不自动清理模拟对象,不手动关闭会导致后续测试失败或内存泄漏:
- 在
setUp()中无需特别操作,但建议在tearDown()末尾加Mockery::close();; - 若使用 PHPUnit 9.3+,可改用
protected function tearDown(): void+parent::tearDown(); Mockery::close();; - 避免在
setUpBeforeClass()中创建全局 mock,因为Mockery::close()会清空全部,容易引发“Undefined index”类错误; - 常用写法示例:
public function tearDown(): void { parent::tearDown(); Mockery::close(); }
Mockery 和 PHPUnit 自带的 createMock() 怎么选
两者不是互斥关系,而是定位不同:
-
$this->createMock(ClassName::class)是 PHPUnit 内置轻量方案,只支持简单方法替换,不支持动态期望、参数约束、返回值链式定义; -
Mockery::mock(ClassName::class)更灵活,能写->shouldReceive('save')->withArgs(['user'])->andReturn(true)->once()这类强约束断言; - 混合使用没问题,但注意:PHPUnit 的 mock 不受
Mockery::close()管理,而 Mockery 创建的 mock 必须 close,否则可能污染下一个测试的 mock 状态; - 如果项目已用大量 PHPUnit 原生 mock,突然引入 Mockery 后出现 “No matching handler found” 错误,大概率是忘了调
Mockery::close(),导致 mock 残留并拦截了不该拦截的方法调用。
close(),这点和大多数 PHP 库习惯相反,容易被忽略。










