Now that we have our resources set up, it's time to ensure they work as expected—and stay that way. In this lesson, we're going to write feature tests for our BankAccount, Budget, and Category resources. We'll focus particularly on ensuring that users can only see their own data.
Setting up Pest
First, we need to add Pest to our project. Pest is a testing framework with a focus on simplicity and elegance.
composer require pestphp/pest --dev --with-all-dependencies
php artisan pest:install
We also need to make sure our User model is ready for Filament testing. To properly simulate a Filament user in our tests, our User model should implement the FilamentUser contract. This ensures that when we use actingAs, the user is correctly recognized as having access to the panel.
Update app/Models/User.php:
use Filament\Models\Contracts\FilamentUser;
// ...
class User extends Authenticatable implements FilamentUser
{
// ...
public function canAccessPanel(\Filament\Panel $panel): bool
{
return true;
}
}
You can view the setup and model changes in this commit.
Testing the Bank Account Resource
Let's start with the BankAccountResource. We want to verify that we can:
- Render the page.
- List bank accounts belonging to the user.
- NOT list bank accounts belonging to other users.
- Create, edit, and delete accounts.
Create a new test file: tests/Feature/Filament/Resources/BankAccountResourceTest.php.
Rendering and Listing
We use actingAs($user) to sign in as a user, and then access the page URL.
use App\Filament\Resources\BankAccounts\Pages\ManageBankAccounts;
use App\Models\BankAccount;
use App\Models\User;
use Livewire\Livewire;
use function Pest\Laravel\actingAs;
it('can render page', function () {
$user = User::factory()->create();
actingAs($user)
->get(ManageBankAccounts::getUrl())
->assertSuccessful();
});
it('can list bank accounts', function () {
$user = User::factory()->create();
$bankAccount = BankAccount::factory()->for($user)->create();
Livewire::actingAs($user)
->test(ManageBankAccounts::class)
->assertCanSeeTableRecords([$bankAccount]);
});
Testing Scope (The "Other User" Test)
This is a critical test. We create a user and another user. We expect the current user effectively not to see the other user's record.
it('cannot see other users bank accounts', function () {
$user = User::factory()->create();
$otherUser = User::factory()->create();
$otherBankAccount = BankAccount::factory()->for($otherUser)->create();
Livewire::actingAs($user)
->test(ManageBankAccounts::class)
->assertCanNotSeeTableRecords([$otherBankAccount]);
});
Actions: Create, Edit, Delete
Filament provides excellent helpers to test actions directly.
it('can create bank account', function () {
$user = User::factory()->create();
Livewire::actingAs($user)
->test(ManageBankAccounts::class)
->mountAction('create')
->setActionData([
'name' => 'My Main Bank',
'balance' => '1000.50',
])
->callMountedAction()
->assertHasNoActionErrors();
assertDatabaseHas('bank_accounts', [
'user_id' => $user->id,
'name' => 'My Main Bank',
'balance' => 100050, // Value as integer thanks to our Caster
]);
});
Notice how we assert the database has the value 100050 because of our logic handling money as integers!
You can see the full test suite for the Bank Account resource in this commit.
Budget and Category Resources
The tests for BudgetResource and CategoryResource follow the exact same pattern. We need to ensure that detailed actions like creating and editing work, but most importantly, we must verify the scoping rules.
For example, the Category tests ensure that a user can only edit their own categories.
You can check the implementation for the Budget resource tests here and the Category resource tests here.
Running the Tests
Finally, let's run our test suite to see everything green!
php artisan test
You should see an output confirming that all resource tests are passing:
PASS Tests\Feature\Filament\Resources\BankAccountResourceTest
✓ it can render page
✓ it can list bank accounts
✓ it cannot see other users bank accounts
...
🎓 Build this App & Get Certified (Free)
If you found this guide helpful, you can build the entire application from scratch with my free course.
What you'll learn:
- 🏗️ Advanced Laravel Architecture
- 📊 Building Dashboards with FilamentPHP
- 💰 Handling Money professionally in code
→ Join other students on maiobarbero.dev
Happy coding!
Top comments (0)