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

Symfony+API Platform中PHPUnit断言JSON浮点值失败问题排查

问题分析与解决方案

这是Symfony序列化组件的默认行为导致的,并非API Platform或你的代码bug。JSON格式本身没有严格区分整数和浮点数类型,当浮点数的值是整数(比如25.0)时,Symfony的NumberNormalizer会自动将其序列化为整数形式(25),而不是保留浮点格式。

解决方法有两种,按需选择:

1. 强制序列化时保留浮点格式

在实体的cost属性上添加Symfony Serializer的Type注解,明确指定该字段序列化为浮点类型:

use Symfony\Component\Serializer\Annotation\Serializer;

#[ApiResource()]
class MyEntity {
    // ...
    #[ORM\Column(nullable: true)]
    #[Serializer\Type('float')]
    private ?float $cost = null;
    // ...
}

添加这个注解后,无论cost的值是25.0还是其他浮点数,API都会返回带小数点的浮点格式,测试的assertJsonContains就能匹配成功。

2. 修改测试逻辑,兼容数值匹配

如果不想修改实体的序列化规则,可以调整测试断言,改用assertEquals比较数值(而非严格匹配数组类型):

public function testGetSingleMyEntity(): void
{
    // ...
    $response = $client->request('GET', '/api/my_entity/'.$myentity->getId());
    $responseData = $response->toArray();
    
    // 比较数值,忽略JSON序列化带来的类型差异
    $this->assertEquals($myentity->getCost(), $responseData['cost'], 'Cost value does not match');
}

assertEquals会忽略整数和浮点数的类型差异,只要数值相等就会通过断言,适合不需要严格保证返回格式的场景。

为什么强制转换没用?

你尝试用(float)或floatval()转换值无效,是因为$myentity->getCost()本身已经是float(25.0)类型,但序列化时Symfony的处理逻辑会把整数值的浮点数自动转成整数,所以API返回的JSON里是25,而assertJsonContains是严格匹配数组的键值对类型,因此导致断言失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 08:01:01