PHPUnit多参数数据提供者报错:无法为int类型属性赋值null
问题解决思路
你遇到的TypeError本质是代码试图将null赋值给声明为int类型的Item::$quality属性,且该问题仅在添加第二个测试用例时触发,说明第二个用例的参数触发了第一个用例未覆盖的逻辑分支,而该分支存在赋值null的漏洞。
排查步骤与解决方案
1. 定位核心逻辑问题(重点检查GildedRose.php第32行)
错误指向GildedRose.php第32行,你需要针对该行代码做如下排查:
- 如果是直接写了
$item->quality = null;,直接修改为符合业务逻辑的int值(比如过期的BackStagePass品质应设为0)。 - 如果是通过计算赋值(比如
$item->quality += $increase;),检查变量$increase是否在所有分支下都被正确初始化:
比如你的BackStagePass品质提升逻辑可能遗漏了sellIn >=10的分支,导致$increase保持初始的null,最终让quality变为null。补全分支即可:// 示例修正后的逻辑 $increase = 1; // 默认提升1点 if ($item->sellIn < 0) { $increase = -$item->quality; // 过期后品质清零 } elseif ($item->sellIn < 5) { $increase = 3; } elseif ($item->sellIn < 10) { $increase = 2; } $item->quality += $increase;
2. 验证数据提供者的参数传递
虽然你当前的数据提供者格式看起来正确,但可以通过调试确认参数是否正常传递:
在测试方法中添加调试输出:
function testBackStagePasses($start,$end) { // 打印参数,确认是否符合预期 var_dump("初始sellIn: {$start[0]}, 初始quality: {$start[1]}"); var_dump("预期sellIn: {$end[0]}, 预期quality: {$end[1]}"); $app = new GildedRose([new BackStagePass($start[0],$start[1])]); $app->updateQuality(); $this->assertEquals($app->items[0]->sellIn,$end[0]); $this->assertEquals($app->items[0]->quality,$end[1]); }
运行测试后,确认第二个用例的参数是否为start=[10,20]、end=[9,22],排除参数解析错误。
3. 单独验证第二个测试用例
使用PHPUnit的--filter参数单独运行第二个用例,确认问题是否仅出现在该用例:
phpunit --filter 'testBackStagePasses#higher_incresae'
4. 检查类型声明与初始化
确保BackStagePass继承的Item类中,quality属性的初始化逻辑正确:
- 构造函数必须为
quality赋予int类型的初始值,不能留空或设为null。 - 所有修改
quality的逻辑都必须保证最终赋值为int类型,避免出现null或非数值类型。
内容的提问来源于stack exchange,提问作者Ivar
相关产品推荐
相关产品推荐

