Laravel中assertJson测试不通过但响应JSON完全匹配问题排查
排查步骤和常见解决方案
- 优先检查字段类型差异
这是assertJson报错最常见的原因,该断言会同时校验字段值和类型,肉眼只看结构很容易忽略类型差异:
- 如果你用了PHP 8.1+的枚举类型作为
customer_type的值,你断言时传入的$customer->customerType是枚举对象,而资源返回时会自动调用枚举的__toString()方法转成字符串,两者类型不匹配会直接报错。这种情况你需要把断言里的customer_type对应值改为$customer->customerType->value或者(string) $customer->customerType。 - 检查
archived字段的类型,确认模型里是否添加了protected $casts = ['archived' => 'boolean'];类型转换,没有的话从数据库取出的archived是字符串格式的0/1,和布尔值判断后得到的Yes/No和实际返回结果可能不一致。 - 其他数值类字段比如
postcode、telephone_number,确认你预期的是数字还是字符串类型,和实际返回的类型是否对齐。
- 打印实际返回结果做精确对比
不要只靠肉眼判断结构一致,在断言前添加代码打印实际返回的JSON内容,和预期值做逐字对比:
$response->assertStatus(200); // 打印实际返回和预期值的JSON字符串,直接对比差异 $expected = json_encode([ 'data' => [ // 你原来写的预期数组 ] ], JSON_PRETTY_PRINT); $actual = json_encode($response->json(), JSON_PRETTY_PRINT); dd($expected, $actual);
如果用的是PHPUnit也可以用$this->assertEquals($expectedArray, $response->json()),报错信息会直接告诉你哪个字段不一致。
确认取到的测试数据正确
你用Customer::first()取的是测试数据库的第一条数据,确认该数据的所有字段值和你预期的一致,没有空值、特殊字符、脏数据的问题。如果你的测试用例没有开启事务回滚或者数据重置,之前测试遗留的脏数据也会导致断言失败。可选:改用宽松匹配方法
如果你只需要验证返回结构正确,不需要验证所有字段值,可以改用assertJsonStructure方法:
$response->assertJsonStructure([ 'data' => [ 'uuid', 'customer_name', 'email', 'slug', 'street_1', 'street_2', 'city', 'postcode', 'telephone_number', 'county', 'customer_type', 'archived' ] ]);
内容的提问来源于stack exchange,提问作者Theory
相关产品推荐
相关产品推荐

