首页 >后端开发 >php教程 >如何在 Laravel 模型中测试相等的 JSON 列

如何在 Laravel 模型中测试相等的 JSON 列

Susan Sarandon
Susan Sarandon原创
2025-01-04 17:05:47851浏览

How to Test for Equal JSON Columns in Laravel Models

在 Laravel 中测试 JSON 列之间的相等性需要特别考虑,因为 JSON 数据在数据库中存储为字符串。在比较 JSON 列时,JSON 编码方式的差异可能会导致意外的测试失败。本文将指导您在 Laravel 应用程序的测试中有效比较 JSON 列。

了解挑战

JSON数据存储到数据库时,是以字符串的形式保存的。 JSON 编码中的微小差异(例如键的间距或顺序)可能会导致直接字符串比较失败。这意味着即使内容在逻辑上是等效的,使用 $this->assertDatabaseHas() 的测试也可能会失败。

模型示例

首先,考虑 PriceSchedule 模型,其中包括 JSON 列:

final class PriceSchedule extends Model
{
    protected $fillable = [
        'user_id',
        'price_supplier_id',
        'weekday',
        'hour',
        'is_active'
    ];

    protected $casts = [
        'weekday' => 'array',
        'hour' => 'array',
    ];
}

工作日和小时属性被转换为数组,以便在应用程序中轻松操作。

编写测试

以下是更新 PriceSchedule 的示例测试:

final class PriceExportScheduleTest extends TestCase
{
    public function test_price_export_schedule_update(): void
    {
        $user = UserFactory::new()->create();
        $this->actingAsFrontendUser($user);

        $priceSchedule = PriceScheduleFactory::new()->make();

        $updatedData = [
            'weekday' => $this->faker->randomElements(DayOfWeek::values(), 3),
            'hour' => $priceSchedule->hour,
            'is_active' => true,
        ];

        $response = $this->putJson(route('api-v2:price-export.suppliers.schedules.update'), $updatedData);

        $response->assertNoContent();

        $this->assertDatabaseHas(PriceSchedule::class, [
            'user_id' => $user->id,
            'is_active' => $updatedData['is_active'],
            'weekday' => $updatedData['weekday'],
            'hour' => $updatedData['hour'],
        ]);
    }
}

JSON 比较的常见问题

使用 $this->assertDatabaseHas() 比较工作日、小时等 JSON 类型值时,由于 JSON 编码的差异,可能会导致直接比较失败。例如:

  • 数据库存储的 JSON: {"key":"value"}
  • PHP 生成的 JSON:{ “键”:“值” }

即使数据在逻辑上相同,测试也可能会因为字符串不同而失败。

解决方案:使用 $this->castAsJson()

为了确保比较一致,请在断言 JSON 列时使用 $this->castAsJson():

$this->assertDatabaseHas(PriceSchedule::class, [
    'user_id' => $user->id,
    'is_active' => $updatedData['is_active'],
    'weekday' => $this->castAsJson($updatedData['weekday']),
    'hour' => $this->castAsJson($updatedData['hour']),
]);

此方法确保测试数据和数据库数据在比较之前都转换为通用的 JSON 格式。

测试输出

运行测试会产生以下结果:

Price Export Schedule (PriceExportSchedule)
✔ Price export schedule update
OK (1 test, 3 assertions)

通过使用 $this->castAsJson(),您可以避免 JSON 编码问题并确保您的测试既可靠又
准确。

以上是如何在 Laravel 模型中测试相等的 JSON 列的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn