Composer怎么安装Mockery库 单元测试模拟对象集成【实操】

6次阅读

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

Composer怎么安装Mockery库 单元测试模拟对象集成【实操】

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 残留并拦截了不该拦截的方法调用。

Mockery 的核心复杂点不在安装,而在生命周期管理——它不靠 GC 自动回收,必须显式 close(),这点和大多数 PHP 库习惯相反,容易被忽略。

text=ZqhQzanResources