CJ Dennis
CJ Dennis

Reputation: 4346

Testing friendly error messages in Laravel 11 on soft deletion failure

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 SoftDeletes 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.',
        ],
      );
    }

Upvotes: 0

Views: 45

Answers (0)

Related Questions