To ensure that LeaveAccount calls DeleteAccount::run() instead of directly deleting the account, you can use a mocking approach in your tests. This way, you can verify that the DeleteAccount::run() method is indeed being called. Here's how you can achieve this using PHPUnit and Laravel's built-in testing capabilities:
-
Mock the
DeleteAccountaction: You can use Laravel'sMockeryto create a mock of theDeleteAccountclass and set expectations on it. -
Set expectations: Ensure that the
runmethod is called with the correct parameters.
Here's an example of how you might write a test for this:
use App\Actions\Account\DeleteAccount;
use App\Actions\Account\LeaveAccount;
use App\Models\Account;
use Illuminate\Support\Facades\Auth;
use Mockery;
use Tests\TestCase;
class LeaveAccountTest extends TestCase
{
public function testLeaveAccountCallsDeleteAccount()
{
// Create a mock for the DeleteAccount action
$deleteAccountMock = Mockery::mock(DeleteAccount::class);
// Set the expectation that the run method will be called once
$deleteAccountMock->shouldReceive('run')
->once()
->with(Mockery::type(Account::class));
// Bind the mock to the service container
$this->app->instance(DeleteAccount::class, $deleteAccountMock);
// Create a test account and user
$account = Account::factory()->create();
$user = User::factory()->create();
// Attach the user to the account
$account->users()->attach($user);
// Simulate the user being authenticated
Auth::shouldReceive('user')->andReturn($user);
// Detach the user from the account
$account->users()->detach($user);
// Call the LeaveAccount action
(new LeaveAccount())->handle($account);
// Verify that the mock's expectations were met
Mockery::close();
}
}
Explanation:
-
Mockery: We use
Mockeryto create a mock of theDeleteAccountclass. This allows us to set expectations on therunmethod. -
Expectation: We expect the
runmethod to be called exactly once with an instance ofAccount. -
Binding the Mock: We bind the mock to the Laravel service container, so when
DeleteAccount::run()is called, it uses our mock instead of the actual class. -
Test Execution: We simulate the scenario where a user leaves an account, and we verify that
DeleteAccount::run()is called when the account has no users left.
This approach ensures that your test will fail if LeaveAccount does not call DeleteAccount::run(), thus enforcing the desired behavior.