Support the ongoing development of Laravel.io →
Laravel Testing Database

I'm testing that if there was a database error on delete that a friendly message is passed to the user. It was working fine, then I changed the model to use soft deletes and it no longer works. The table has been migrated and the trait added to the model. Testing for a successful soft delete passes. What's happening is that the original object is being passed to the controller instead of the mock object, resulting in the object being soft deleted and no error message passed back. If I try to override delete() on the class instead of on the object instance, destroy() on the controller doesn't get called.

How can I get this test working?

Test

public function test_should_handle_deletion_failure() {
  $user = Models\User::factory()->create();
  $this->actingAs($user);

  $definition = Models\Definition::factory()->create();

  $mockDefinition = Mockery::mock($definition)->makePartial();
  $mockDefinition->shouldReceive('delete')->once()->andThrow(new \Exception('Deletion error'));

  $this->app->instance(Models\Definition::class, $mockDefinition);

  $response = $this->delete("/definition/{$definition->id}");

  $response->assertInertia(
    fn(AssertableInertia $page) => $page->component('Definition/Index')->where('error', 'An error occurred while deleting the definition. Please try again.'),
  );

  $this->assertNotSoftDeleted( // was `$this->assertDatabaseHas` before changing to soft deletes
    'definitions',
    [
      'id' => $definition->id,
    ],
  );
}

Controller code

public function destroy(Models\Definition $definition): Inertia\Response {
  try {
    $definition->delete();
  }
  catch (Throwable $e) {
    Log::error('Error deleting definition: ' . $e->getMessage());

    return Inertia\Inertia::render(
      'Definition/Index',
      [
        'definitions' => Models\Definition::all(),
        'error' => 'An error occurred while deleting the definition. Please try again.',
      ],
    );
  }

  return Inertia\Inertia::render(
    'Definition/Index',
    [
      'definitions' => Models\Definition::all(),
      'success' => 'Definition deleted successfully.',
    ],
  );
}
0

Sign in to participate in this thread!

Eventy

Your banner here too?

Daniel Klein cjdennis Joined 26 Sep 2024

Moderators

We'd like to thank these amazing companies for supporting us

Your logo here?

Laravel.io

The Laravel portal for problem solving, knowledge sharing and community building.

© 2025 Laravel.io - All rights reserved.