Mockery/PHPUnit:如何Mock同名父类方法的返回值
在Mockery中测试子类调用父类方法的场景
你的核心问题是partial mock会覆盖子类的目标方法,导致无法测试真实逻辑。针对你的代码场景(父类getName无参,子类getName带bool参数),可以通过参数匹配实现仅Mock父类的同名方法,保留子类方法的真实执行逻辑。
具体实现代码
// 创建Child类的partial mock,保留子类方法的真实逻辑 $child = Mockery::mock(Child::class)->makePartial(); // 仅Mock父类的无参getName方法,指定返回值 $child->shouldReceive('getName') ->withNoArgs() ->thenReturn('mocked_parent'); // 测试分支1:参数为true时,返回子类自身结果 $this->assertEquals('child', $child->getName(true)); // 测试分支2:参数为false时,返回Mock的父类方法结果 $this->assertEquals('mocked_parent', $child->getName(false));
扩展场景:父类与子类方法参数相同
如果父类和子类的getName方法参数完全一致,无法通过参数区分,推荐通过重构子类代码降低测试复杂度:
- 把
parent::getName()的调用封装为独立的受保护方法 - 测试时Mock这个受保护方法即可
修改后的Child类:
class Child extends Parent { public function getName(bool $someParameter) { if ($someParameter) { return 'child'; } return $this->callParentGetName(); } protected function callParentGetName() { return parent::getName(); } }
对应的测试代码:
$child = Mockery::mock(Child::class)->makePartial(); // Mock受保护的callParentGetName方法 $child->shouldReceive('callParentGetName') ->andReturn('mocked_parent'); $this->assertEquals('child', $child->getName(true)); $this->assertEquals('mocked_parent', $child->getName(false));
内容的提问来源于stack exchange,提问作者Jimmyb_1991
相关产品推荐
相关产品推荐

