PHP $this->{$this->name}、...\array_values语法及PHPUnit报错咨询
问题解答
报错直接原因
testGetList()测试方法声明了1个必填形参,但PHPUnit运行时未获取到需要传入的对应参数,传入参数数量为0,因此触发ArgumentCountError。
PHPUnit不会自动给测试方法注入依赖,仅当测试方法配置了*@dataProvider数据提供器、或@testWith*测试数据集注解时,才会从配置的数据源中取参数传入测试方法。你当前的测试方法写了入参但未配置对应参数来源,$testArguments为空数组,最终传参数量为0。
代码行语法解释
你看到的$testResult = $this->{$this->name}(...\array_values($testArguments));是PHP的动态调用+参数展开语法,各部分含义如下:
$this->name:PHPUnit内部存储的当前待执行测试方法名,本次报错场景下该值为字符串testGetList$this->{$this->name}:PHP动态方法调用写法,等价于直接调用$this->testGetList(),区别是方法名从变量动态读取,适配不同测试方法的执行逻辑\array_values():前面的反斜杠\是PHP全局命名空间前缀,明确指定调用PHP内置的全局函数array_values(),避免当前命名空间下存在同名函数时产生调用错误- 前面的
...是PHP的参数展开运算符(Spread Operator),作用是把后续数组的每个元素,按顺序作为独立参数传入被调用的方法。如果$testArguments是[$mockSearchCriteria],展开后等价于给方法传1个参数$mockSearchCriteria;如果数组为空,展开后就是给方法传0个参数。
整行代码的实际作用就是:动态调用当前需要执行的测试方法,把收集到的测试参数按顺序传入,拿到测试执行结果。
修复方案
根据你的测试逻辑二选一即可:
- 若
testGetList不需要外部传参,直接删除方法定义中的形参声明即可 - 若需要通过不同入参覆盖多测试场景,给测试方法添加对应的数据提供器,示例代码如下:
<?php namespace Magenio\Todo\Test\Unit\Service; use Magento\Framework\Api\SearchCriteria; use PHPUnit\Framework\TestCase; class TaskRepositoryTest extends TestCase { /** * @dataProvider getListTestProvider */ public function testGetList(SearchCriteria $searchCriteria) { // 原有测试逻辑 } public function getListTestProvider() { return [ // 每一个子数组对应一次测试调用的参数列表 [$this->createMock(SearchCriteria::class)] ]; } }
内容的提问来源于stack exchange,提问作者Gianmarco Polizia
相关产品推荐
相关产品推荐

