在ThinkPHP项目中需用Mockery隔离测试外部依赖,步骤包括:一、安装兼容的Mockery与PHPUnit并配置自动加载和phpunit.xml;二、配置Mockery适配器,在TestCase中初始化和清理;三、通过重绑定门面类(如Db)实现静态调用模拟;四、对Model进行部分模拟并从容器获取实例以保障生命周期;五、使用次数限制、类型匹配和闭包校验参数,并最终断言期望满足。

如果您在ThinkPHP项目中需要对依赖外部服务的逻辑进行隔离测试,则必须引入Mockery来创建可控的模拟对象。以下是将Mockery集成到ThinkPHP并正确使用的具体步骤:
一、安装Mockery与PHPUnit
Mockery需作为开发依赖安装,且必须与PHPUnit版本兼容。ThinkPHP 8.x基于PHP 8.1+,应避免使用过时版本。
1、在项目根目录执行Composer命令安装最新稳定版:composer require --dev phpunit/phpunit ^10 mockery/mockery ^1.6
2、确认composer.json的autoload-dev段已包含"tests/": "tests/"映射,确保测试类可被自动加载。
3、手动创建phpunit.xml文件,至少定义<testsuites></testsuites>和<source></source>路径,否则TestCase类无法识别。
二、配置Mockery适配器并初始化
Mockery需通过PHPUnit适配器接入测试生命周期,确保Mockery::close()在每个测试后自动调用,防止期望未满足导致误报。
1、在tests/TestCase.php基类的setUp()方法中添加:$this->setUpMockery();
2、在同文件的tearDown()方法中添加:Mockery::close();
3、若使用自定义测试基类,需继承Mockery\Adapter\Phpunit\MockeryTestCase而非原始PHPUnit\Framework\TestCase。
三、Mock ThinkPHP门面类(如Db)
ThinkPHP的Db是门面类,静态调用链由容器代理,直接Mock连接实例会导致方法不可达。必须替换门面绑定以拦截全部静态访问。
1、在测试类setUp()中创建模拟对象:$mockDb = Mockery::mock('alias:think\Db');
2、重绑定门面:$this->app->bind('think\Db', $mockDb);
3、设定期望行为,例如模拟查询返回空数组:$mockDb->shouldReceive('table')->with('user')->andReturnSelf(); $mockDb->shouldReceive('select')->andReturn([]);
四、对Model类进行部分模拟
当需测试Model中部分方法而保留其余真实逻辑(如字段自动转换、初始化钩子)时,应采用部分模拟,避免绕过容器导致$this->db为null或initialize()未执行。
1、使用mock指定仅模拟特定方法:$mockUser = Mockery::mock('MyApp\Model\User[getUserByTag]');
2、为模拟方法设定返回值:$mockUser->shouldReceive('getUserByTag')->with('admin')->andReturn(['id' => 1, 'name' => 'admin']);
3、从容器获取该模型实例以保障完整生命周期:$user = $this->app->make('MyApp\Model\User', ['mock' => $mockUser]);
五、验证方法调用与参数匹配
Mockery支持细粒度的行为断言,可用于验证被测代码是否按预期调用了依赖方法及其参数内容。
1、限定调用次数并验证参数类型:$mockDb->shouldReceive('where')->times(2)->with(Mockery::type('array'))->andReturnSelf();
2、使用闭包匹配器校验复杂参数结构:$mockDb->shouldReceive('insert')->with(Mockery::on(function ($args) { return is_array($args) && isset($args['status']) && $args['status'] === 1; }))->andReturn(1);
3、在测试末尾显式断言所有期望已被满足:$this->assertTrue(Mockery::getContainer()->isSatisfied());
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











