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

PHPUnit:如何对同一方法的多次调用进行Mock

解决Mock方法多次调用返回不同值的问题

Hey there! Let's sort out how to get distinct return values from your mocked method when it's called multiple times. The problem with your current code is that $this->second() isn't a valid matcher in PHPUnit—luckily, we have several straightforward solutions for this scenario.

方法1:使用onConsecutiveCalls()(最简洁)

这是PHPUnit专门为连续调用返回不同值设计的方法,用法非常直观:

$mock = $this->getMockBuilder('Test')
    ->disableOriginalConstructor()
    ->setMethods(['testMethod'])
    ->getMock();

// 指定方法被调用2次,按顺序返回true、false
$mock->expects($this->exactly(2))
    ->method('testMethod')
    ->will($this->onConsecutiveCalls(true, false));

exactly(2)确保方法被调用恰好2次,onConsecutiveCalls()会按传入参数的顺序依次返回对应值。

方法2:使用at()匹配器(精准指定调用顺序)

如果你需要精准控制某一次调用的返回值,可以用at(),注意调用索引从0开始计数:

$mock = $this->getMockBuilder('Test')
    ->disableOriginalConstructor()
    ->setMethods(['testMethod'])
    ->getMock();

// 第1次调用(索引0)返回true
$mock->expects($this->at(0))
    ->method('testMethod')
    ->will($this->returnValue(true));

// 第2次调用(索引1)返回false
$mock->expects($this->at(1))
    ->method('testMethod')
    ->will($this->returnValue(false));

⚠️ 注意:at()是针对所有Mock方法的全局调用顺序,不是当前方法的单独调用顺序。如果你的测试里还有其他Mock方法被调用,索引会累加,这点要留意。

方法3:使用returnCallback()(灵活处理复杂逻辑)

如果需要更复杂的返回逻辑(比如根据参数、调用次数动态返回),可以用回调函数:

$mock = $this->getMockBuilder('Test')
    ->disableOriginalConstructor()
    ->setMethods(['testMethod'])
    ->getMock();

$callCount = 0;
$mock->expects($this->exactly(2))
    ->method('testMethod')
    ->will($this->returnCallback(function() use (&$callCount) {
        $callCount++;
        // 根据调用次数返回对应值,也可以扩展成根据参数判断的逻辑
        return $callCount === 1 ? true : false;
    }));

总结

如果只是简单的连续调用返回固定顺序的值,方法1的onConsecutiveCalls()是最优选择,代码简洁且语义明确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:27:18