You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHPUnit模拟Doctrine ArrayCollection时toArray()返回null问题求助

解决Doctrine ArrayCollection Mock对象toArray()返回null的问题

问题原因

用PHPUnit的getMockBuilder()->getMock()创建ArrayCollection的mock对象时,默认会替换该类的所有方法为返回null的mock实现——哪怕你通过构造函数传入了元素,toArray()方法也不会执行原类的逻辑,自然返回null,导致array_map触发类型错误。

解决方案

方案1:手动指定toArray()的返回值

在创建完ArrayCollection的mock后,为toArray()方法设置预期返回值:

$subEntity = $this->createMock(SubEntity::class);

$arrayCollection = $this->getMockBuilder(ArrayCollection::class)
    ->setConstructorArgs([[$subEntity]])
    ->getMock();

// 新增:指定toArray()返回包含子实体的数组
$arrayCollection->expects($this->once())
    ->method('toArray')
    ->willReturn([$subEntity]);

$entity = $this->createMock(Entity::class);
$entity
    ->expects($this->once())
    ->method('getSubEntities')
    ->willReturn($arrayCollection);

// 后续测试代码不变
$testingClass = new TestingClass();
$result = $testingClass->converts($entity);

$this->assertInstanceOf(OtherEntity::class, $result);

方案2:保留原类的toArray()实现

如果不需要mock ArrayCollection的任何方法,直接使用onlyMethods([])创建mock,这样会保留原类的所有方法逻辑:

$subEntity = $this->createMock(SubEntity::class);

$arrayCollection = $this->getMockBuilder(ArrayCollection::class)
    ->setConstructorArgs([[$subEntity]])
    ->onlyMethods([]) // 不mock任何方法,使用原类的实现
    ->getMock();

// 后续测试代码不变
$entity = $this->createMock(Entity::class);
$entity
    ->expects($this->once())
    ->method('getSubEntities')
    ->willReturn($arrayCollection);

$testingClass = new TestingClass();
$result = $testingClass->converts($entity);

$this->assertInstanceOf(OtherEntity::class, $result);

这两种方法都能让$arrayCollection->toArray()返回预期的数组,解决array_map的类型错误。

内容的提问来源于stack exchange,提问作者Tommy Hoang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 16:40:55