在 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'], ]); } }
使用 $this->assertDatabaseHas() 比较工作日、小时等 JSON 类型值时,由于 JSON 编码的差异,可能会导致直接比较失败。例如:
即使数据在逻辑上相同,测试也可能会因为字符串不同而失败。
为了确保比较一致,请在断言 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中文网其他相关文章!