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

PHP Mock测试报方法预期调用1次实际0次异常排查

问题现象

测试执行时抛出错误:
Method should be called exactly 1 times but called 0 times

测试代码如下:

$mock = $this->mock(GetAll::class);
$mock->shouldReceive('setCustomersQueryParametersDto')
     ->once()
     ->with($customerDto)
     ->andReturnSelf();

$mock->shouldReceive('execute')->once()->andReturn(collect([])); 

$this->actingAs($user)->json('GET', $this->generateUrl());

测试逻辑预期:GetAll类调用execute方法前,必须先调用setter方法setCustomersQueryParametersDto传入DTO对象。Mock配置已按调用顺序先定义setter规则:预期调用1次、入参为$customerDto、返回Mock对象自身;后续定义execute方法规则:预期调用1次、返回空集合。最后模拟登录用户发起GET请求访问接口,预期测试正常通过,但实际运行时控制器内execute方法返回结果不符合预期。
控制器内对应业务代码如下:

$this->getAllAction->setCustomersQueryParametersDto($customersRequest->model())->execute();
问题原因

核心问题出在两个地方:

  1. 参数严格匹配不通过:Mockery(Laravel测试Mock功能的底层库)默认对with()传入的参数做对象引用级别的严格校验,要求传入的参数必须和测试代码中提前创建的$customerDto是同一个实例。但控制器中实际传入的是请求运行时通过$customersRequest->model()动态生成的新DTO实例,哪怕两个实例属性完全一致,因为不是同一个对象引用,会被判定为参数不匹配,导致setter方法的Mock规则完全未命中。
  2. 规则未命中后,setter方法不会按预期返回Mock实例自身,后续链式调用的execute方法自然也无法命中提前配置的Mock规则,最终触发「方法预期调用1次实际调用0次」的报错。
修复方案

按以下步骤调整测试代码即可:

  1. 替换参数匹配规则,放弃对象引用的严格校验,改为校验传入DTO的属性值是否符合预期
  2. 可选添加ordered()标记,明确两个方法的调用先后顺序,避免链式调用规则承接异常

修复后的测试代码示例:

$mock = $this->mock(GetAll::class);
$mock->shouldReceive('setCustomersQueryParametersDto')
     ->once()
     // 改为值匹配,只要传入的DTO属性和预期一致即判定通过,不要求是同一个实例
     ->with(\Mockery::on(function($actualDto) use ($customerDto) {
         // 以下三种值比对方式三选一即可,按需选择
         // 1. 如果DTO自带equals方法:return $actualDto->equals($customerDto);
         // 2. 如果DTO可以转数组:return $actualDto->toArray() === $customerDto->toArray();
         // 3. 通用PHP对象值比对:return $actualDto == $customerDto;
     }))
     ->andReturnSelf()
     ->ordered(); // 标记调用顺序:setter必须先执行

$mock->shouldReceive('execute')
     ->once()
     ->andReturn(collect([]))
     ->ordered(); // 标记调用顺序:execute在setter之后执行

$this->actingAs($user)->json('GET', $this->generateUrl());

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 20:54:19