You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel使用Mockery模拟时报错No matching handler,求解决方案

解决Mockery匹配Laravel模型实例的问题

遇到这个错误核心原因是Mockery默认严格匹配对象的内存实例——如果测试里你期望的Message实例和实际传给execute的不是同一个内存对象,就会触发无匹配的异常。下面给你几个实用的解决办法:

1. 自定义属性匹配(最常用)

不用纠结是不是同一个实例,直接检查模型的关键属性(比如id)是否符合预期,用Mockery::on()实现:

// 先定义期望的模型和更新数据
$expectedMessage = Message::factory()->make(['id' => 123]);
$expectedUpdateData = ['content' => '新的消息内容'];

// 创建Mock对象
$actionMock = Mockery::mock(MessageUpdateAction::class);
$actionMock->shouldReceive('execute')
    ->once()
    ->with(
        // 自定义匹配逻辑:检查传入的message的id和期望的一致
        Mockery::on(function($message) use ($expectedMessage) {
            return $message->id === $expectedMessage->id;
        }),
        // 直接匹配更新数据
        $expectedUpdateData
    );

// 绑定到容器,让业务逻辑使用这个Mock
$this->app->instance(MessageUpdateAction::class, $actionMock);

// 执行你的测试逻辑,比如调用控制器方法

这种方式不管业务逻辑里是直接传模型实例还是重新查询后传递,只要id匹配就能通过,适合大部分场景。

2. 确保使用同一个内存实例

如果你确实需要验证是同一个对象,那要保证测试中传递的和业务逻辑里用的是同一个实例:

// 创建一个实际的模型实例(用create存入数据库,避免重新查询生成新实例)
$message = Message::factory()->create();
$updateData = ['content' => '更新内容'];

$actionMock = Mockery::mock(MessageUpdateAction::class);
$actionMock->shouldReceive('execute')
    ->once()
    ->with($message, $updateData);

$this->app->instance(MessageUpdateAction::class, $actionMock);

// 执行业务逻辑时,确保传入的是上面的$message,而不是重新查询的实例
// 比如控制器方法里直接用传入的$message,而不是Message::find($id)

注意:如果业务逻辑里有重新查询模型的操作(比如Message::find($message->id)),会生成新的内存实例,这时候严格匹配就会失败,这种情况还是用第一种方法更靠谱。

3. 匹配类型+数据验证

如果只需要确保传入的是Message类型,同时更新数据正确,可以结合Mockery::type()和自定义匹配:

$actionMock->shouldReceive('execute')
    ->once()
    ->with(
        Mockery::type(Message::class),
        Mockery::on(function($data) use ($expectedUpdateData) {
            return $data === $expectedUpdateData;
        })
    );

另外,测试后别忘了清理Mockery,避免内存泄漏:

protected function tearDown(): void
{
    parent::tearDown();
    Mockery::close();
}

内容的提问来源于stack exchange,提问作者Bubble Initiative

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 09:07:20