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

PHP Prophecy测试void方法调用断言时触发UnexpectedCallException错误

问题解决:Prophecy验证void方法调用时触发UnexpectedCallException

核心问题是你没有把生成的Mock实例注入到被测试的业务逻辑中,导致实际执行execute方法的对象,不是你设置了shouldBeCalled断言的那个Mock对象。

修正步骤

  • 保存reveal()生成的Mock实例,不要调用后直接丢弃
  • 将这个实例传入到需要调用它的被测试代码中(比如被测试类的构造函数、方法参数)
  • 触发被测试逻辑,确保它会调用这个Mock的execute方法

修正后的代码示例

public function testFoo()
{
    $fooMock = $this->prophet->prophesize(Foo::class);
    // 断言execute方法会被调用
    $fooMock->execute()->shouldBeCalled();
    // 生成实际可用的Mock实例并保存
    $fooInstance = $fooMock->reveal();

    // 关键:把Mock实例注入到被测试逻辑中(根据你的实际代码调整)
    // 示例:假设被测试类需要依赖Foo实例
    $testedService = new TestedService($fooInstance);
    // 触发业务逻辑,使其调用fooInstance->execute()
    $testedService->triggerExecute();
}

为什么“不被调用”的用例正常?

当你用shouldNotBeCalled时,只要没把这个Mock实例投入使用,自然不会有任何调用,预言会直接通过。但shouldBeCalled要求这个Mock必须被调用到,没注入的话要么实际调用的是其他对象,要么根本没调用,Prophecy就会抛出意外调用的错误。

额外排查点:如果execute方法有参数,要确保断言时的参数匹配实际调用的参数,比如$fooMock->execute('expectedArg')->shouldBeCalled();,参数不匹配也会触发同样的错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 11:37:03