Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

n8udd's avatar
Level 12

Unexpected DateTime Format in assertDatabaseHas Method with Date when testing

Laravel Version

10.39.0

PHP Version

8.3

Database Driver & Version

8.0.33

Description

When using the assertDatabaseHas method in tests, there seems to be an inconsistency with how date fields are handled.

Despite the field being cast as a date in the Eloquent model and stored as a date in the MySQL database, the assertDatabaseHas method is returning the date as a datetime string.

This causes the assertion to fail when comparing the date value from the test data with the date value from the database.

Steps To Reproduce

Migration: $table->date('due_date')->nullable();

Model: protected $casts = ['due_date' => 'date:Y-m-d'];

Factory: 'due_date' => now()->addDays(fake()->numberBetween(1, 365))->format('Y-m-d'),

Test:

it('should test correctly', function () {
  $owner = User::factory()->create();
  $this->actingAs($owner);

  $this->assertDatabaseCount('deliveries', 0);

  $delivery_data = Delivery::factory()->make()->toArray();

  $response = $this->postJson(route('me.deliveries.store'), $delivery_data);

  $this
    ->assertDatabaseCount('deliveries', 1)
    ->assertDatabaseHas('deliveries', [
      'title' => $delivery_data['title'],
      'description' => $delivery_data['description'],
      'due_date' => $delivery_data['due_date'],
      'visibility' => $delivery_data['visibility'],
      'user_id' => $owner->id,
    ]);
});

Result:

Tests\Feature\API\Controllers\MeDeliveryStoreTest > it should test correctly                               
  Failed asserting that a row in the table [deliveries] matches the attributes {
    "title": "Maiores tempore enim fuga qui.",
    "description": "Iure ipsum tempora est sequi et optio. Omnis rerum qui architecto officiis. Deleniti quos et harum et nobis. Nobis veniam excepturi corrupti placeat.",
    "due_date": "2024-12-03",
    "visibility": "public",
    "user_id": 1,
}.

Found similar results: [
    {
        "title": "Maiores tempore enim fuga qui.",
        "description": "Iure ipsum tempora est sequi et optio. Omnis rerum qui architecto officiis. Deleniti quos et harum et nobis. Nobis veniam excepturi corrupti placeat.",
        "due_date": "2024-12-03 00:00:00",
        "visibility": "public",
        "user_id": 1,
    }
].

  at tests/Feature/API/Controllers/MeDeliveryStoreTest.php:21
     17▕   $response = $this->postJson(route('me.deliveries.store'), $delivery_data);
     18▕ 
     19▕   $this
     20▕     ->assertDatabaseCount('deliveries', 1)
  ➜  21▕     ->assertDatabaseHas('deliveries', [
     22▕       'title' => $delivery_data['title'],
     23▕       'description' => $delivery_data['description'],
     24▕       'due_date' => $delivery_data['due_date'],
     25▕       'visibility' => $delivery_data['visibility'],


  Tests:    1 failed (3 assertions)
  Duration: 0.63s
0 likes
4 replies
n8udd's avatar
Level 12

@krs I mention in the post that I am casting to date on the model Y-m-d.

The format is correct in the application and if I use tinkerwell. It returns just a date as expected.

It's specifically with this test, and the assertDatabaseHas method that's not returning the data correctly.

klopma's avatar

@n8udd Hello! Curious whether you even found a solution on this front? I'm now experiencing a similar issue.

Please or to participate in this conversation.