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

