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

Mockery部分模拟类内部调用的公共方法失效问题求助

解决Mockery部分模拟时内部方法调用未被拦截的问题

问题原因

当使用makePartial()创建Inventory类的部分模拟对象时,只有被shouldReceive显式声明的方法会被Mockery代理拦截。你的remove方法调用的是类的原始实现,此时方法内部的$this->substract()会直接执行原始逻辑,而非你模拟的版本——因为原始代码里的$this指向真实的类实例,没有经过Mockery的代理层。

解决方案

方案一:让remove方法通过Mockery代理(推荐)

通过passthru()让remove方法走Mockery代理层,同时保留原始实现,这样内部的$this->substract()调用会被拦截到模拟方法:

$mock = \Mockery::mock(Inventory::class)->makePartial();
// 让remove走代理并保留原始逻辑
$mock->shouldReceive('remove')->passthru();
$mock->shouldReceive('substract')->andReturn(0);
dd($mock->remove(10)); // 返回预期的0

方案二:手动重写remove方法逻辑

创建完整模拟对象,手动实现remove的原始逻辑,确保调用的是模拟的substract:

$mock = \Mockery::mock(Inventory::class);
// 手动实现remove的业务逻辑
$mock->shouldReceive('remove')->andReturnUsing(function(int $value) use ($mock) {
    return $mock->substract($value, 1);
});
$mock->shouldReceive('substract')->andReturn(0);
dd($mock->remove(10)); // 返回0

额外建议

如果substract方法仅作为内部逻辑使用,不需要对外暴露,建议将其修改为protected访问修饰符,这样Mockery可以更便捷地模拟内部方法,同时避免外部不必要的调用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 12:27:29