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
相关产品推荐
相关产品推荐

