在 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中文網其他相關文章!