Symfony单元测试报错:$databaseDirPath未初始化即访问
单元测试获取Kernel根目录时的初始化错误解决方法
问题代码
我在单元测试的setUp方法中尝试获取Kernel根目录,代码如下:
private string $databaseDirPath; protected function setUp(): void { parent::setUp(); self::bootKernel(); $container = static::getContainer(); $this->databaseDirPath = $container->getParameter('kernel.root_dir').'/resources/database/' ; } /** * @dataProvider provideInexistentFile */ public function testConvertReturnNull(string $file):void { if (!file_exists($file) || !is_readable($file)) { $response = null; } $this->assertNull($response); } public function provideInexistentFile(): array { return [ 'inexistent file' => [ $this->databaseDirPath. 'comdfsasd.csv', ], 'inexistent file' => [ $this->databaseDirPath. 'gbfdgbzsa.csv', ], ]; }
错误信息
$databaseDirPath 不得在初始化前访问
问题原因
PHPUnit的数据提供者方法(provideInexistentFile)会在setUp方法执行之前运行,此时实例属性$databaseDirPath还未被赋值,直接访问会触发未初始化错误。另外,数据提供者默认在静态上下文执行,无法直接访问实例化后的类属性。
解决方案
方案一:数据提供者中直接获取容器参数
将数据提供者改为静态方法,在内部启动Kernel并获取根目录参数:
public static function provideInexistentFile(): array { self::bootKernel(); $container = static::getContainer(); $databaseDirPath = $container->getParameter('kernel.root_dir').'/resources/database/'; return [ '不存在的文件1' => [ $databaseDirPath . 'comdfsasd.csv', ], '不存在的文件2' => [ $databaseDirPath . 'gbfdgbzsa.csv', ], ]; }
方案二:测试方法内拼接文件路径
让数据提供者返回文件名,在测试方法中结合已初始化的$databaseDirPath拼接完整路径:
/** * @dataProvider provideInexistentFile */ public function testConvertReturnNull(string $fileName):void { $file = $this->databaseDirPath . $fileName; $response = file_exists($file) && is_readable($file) ? null : null; // 此处替换为实际业务处理逻辑 $this->assertNull($response); } public function provideInexistentFile(): array { return [ '不存在的文件1' => ['comdfsasd.csv'], '不存在的文件2' => ['gbfdgbzsa.csv'], ]; }
方案三:使用静态属性提前初始化
在setUpBeforeClass(类初始化阶段)中获取根目录并赋值给静态属性,数据提供者直接访问静态属性:
private static string $databaseDirPath; public static function setUpBeforeClass(): void { parent::setUpBeforeClass(); self::bootKernel(); $container = static::getContainer(); self::$databaseDirPath = $container->getParameter('kernel.root_dir').'/resources/database/'; } public function provideInexistentFile(): array { return [ '不存在的文件1' => [ self::$databaseDirPath . 'comdfsasd.csv', ], '不存在的文件2' => [ self::$databaseDirPath . 'gbfdgbzsa.csv', ], ]; }
内容的提问来源于stack exchange,提问作者balda
相关产品推荐
相关产品推荐

