Reputation: 4346
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?
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,
],
);
}
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