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

Laravel中Mockery部分模拟仍接收全部方法调用问题排查

问题原因

你出现这个报错的核心原因是:你是对接口MyServiceInterface做的部分模拟,而不是对实现类myService做的部分模拟。
接口本身只有方法签名,没有实际的方法实现逻辑,Mockery的部分模拟没有可以 fallback 的原有执行逻辑,所以所有被调用的方法都必须预先声明调用预期,否则就会抛出你遇到的BadMethodCallException。

解决方案

你可以选以下任意一种方案处理:

方案1:改为对实现类做部分模拟(推荐)

将部分模拟的目标从接口换成你的服务实现类,同时将模拟实例绑定到服务容器的接口标识上,这样未声明预期的cleanString方法就会自动走原有实现:

$this->mock = $this->partialMock(\App\Services\myService::class, function (MockInterface $mock) use ($testData) {
    $mock->shouldReceive('method1')->andReturn(null);
    $mock->shouldReceive('method2')->andReturn($testData[0]);
    $mock->shouldReceive('method3')->andReturn(count($testData) - 1);
    $mock->shouldReceive('method4')->andReturn(array_slice($testData, 1), false);
});
// 绑定模拟实例到接口,保证依赖注入时能拿到模拟对象
$this->app->bind(MyServiceInterface::class, fn() => $this->mock);

方案2:给cleanString补充调用预期

如果你必须保留对接口的模拟,可以直接给cleanString方法加预期,调用真实服务的对应逻辑:

$this->mock = $this->partialMock(MyServiceInterface::class, function (MockInterface $mock) use ($testData) {
    // 原有其他方法的预期保留
    $mock->shouldReceive('method1')->andReturn(null);
    $mock->shouldReceive('method2')->andReturn($testData[0]);
    $mock->shouldReceive('method3')->andReturn(count($testData) - 1);
    $mock->shouldReceive('method4')->andReturn(array_slice($testData, 1), false);
    // 新增cleanString的预期,走真实实现逻辑
    $mock->shouldReceive('cleanString')->andReturnUsing(fn($string) => (new \App\Services\myService)->cleanString($string));
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 10:48:04