如何在PHP单元测试中访问函数局部变量$bread并执行assertEquals断言
PHP单元测试访问方法内局部变量的解决方案
首先需要明确:方法内的局部变量会在方法执行完成后自动销毁,正常情况下无法从外部直接访问,强行通过hack手段获取内部局部变量做测试也不符合单元测试的设计原则,单元测试应优先测试方法的对外公开行为而非内部实现细节。以下提供两种可行方案:
方案1:修改原方法添加返回值(推荐)
你当前的levels方法仅对局部变量$bread赋值但没有任何对外输出,本身就缺少可测的公开行为,建议直接修改方法返回$bread,这是成本最低、最符合开发规范的实现:
public function levels($id){ // 预先初始化避免未传匹配id时变量未定义的问题 $bread = ''; switch($id){ case 5: $bread = 'N2'; break; case 1: $bread = 'N1'; break; } return $bread; }
修改完成后即可在测试类中直接调用方法获取结果做断言:
// TestControllerTest 中的测试方法 public function testLevelsReturnCorrectValue() { $target = new 你的实际类名(); // 断言id=1时返回N1 $this->assertEquals('N1', $target->levels(1)); // 断言id=5时返回N2 $this->assertEquals('N2', $target->levels(5)); // 可补充测试其他id的默认返回结果 $this->assertEquals('', $target->levels(99)); }
方案2:特殊场景下的hack方案(不推荐)
如果你完全不能修改原方法的代码(比如是第三方依赖的内部方法),可以通过安装runkit7扩展重写方法,注入逻辑捕获局部变量:
- 安装runkit7扩展(仅支持PHP7+版本)
- 在测试方法中临时重写
levels方法,将$bread的值存入全局变量或者类属性后再做断言,测试完成后要恢复原方法避免影响其他测试逻辑。
该方案和方法内部实现强耦合,一旦原方法内部逻辑调整,测试代码就会失效,仅建议作为临时调试手段使用,不适合作为长期自动化测试方案。
内容的提问来源于stack exchange,提问作者Nghiem Hung
相关产品推荐
相关产品推荐

