lucasmelocvl / laravel-model-unit-testing
Artisan command to automatically generate and merge structural unit tests for all Laravel Eloquent models.
Package info
github.com/lucasmelocvl/laravel-model-unit-testing
pkg:composer/lucasmelocvl/laravel-model-unit-testing
Requires
- php: ^7.3|^8.0
- illuminate/console: ^5.8|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0
- illuminate/database: ^5.8|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0
- illuminate/support: ^5.8|^6.0|^7.0|^8.0|^9.0|^10.0|^11.0
README
Eloquent models are the absolute bedrock of any Laravel application. They represent your business logic, govern data transformations, and guard database integrity. Yet, model configurations are prone to silent, devastating drift:
- A column is renamed in a migration, but the
$fillablearray is never updated. - A foreign key name changes, silently breaking an Eloquent relationship method.
- A developer forgets to cast an attribute to
booleanorinteger, causing runtime type bugs. - Missing database tables or obsolete definitions linger unnoticed.
Writing individual, boiler-plate unit tests for dozens of models is mind-numbing and instantly becomes stale.
laravel-model-unit-testing is a premium, zero-maintenance structural testing suite that shields your Eloquent models from schema drift. By dynamically reflecting your models and checking them directly against your active database schema, it detects structural regressions in milliseconds.
⚡ The Smart-Merge Advantage
Many generators are destructive: they overwrite your test files and wipe out custom test methods you worked hard to build.
Our generator is designed with a Defensive Smart-Merge Engine. When you run the generator with the --force flag:
- It parses your existing test file to identify custom test methods and extra PHP
useimports. - It regenerates only the structural expectations (like
expectedTable(),expectedFillable(),expectedRelationships()). - It safely injects your custom test methods and imports back into the class, completely preserved.
Your custom tests will never be lost.
✨ Key Features
- 🔍 Full Automatic Discovery: Searches all nested subfolders (
app/Models/**/*.php) to discover all models recursively. - 📋 Configuration Validation: Automatically asserts exact alignment for
$table,$primaryKey,$incrementing, and$keyType. - 🛡️ Attribute Security: Asserts the exact lists of
$fillable,$guarded,$hidden, and$appends. - 💎 Database Alignment: Verifies that all fillable, hidden, and date fields actually exist in the database schema.
- ⚙️ Cast Verification: Compares Eloquent casts (e.g.
integer,boolean) against real database column types (e.g.INT,TINYINT) to spot mismatches. - 🔗 Deep Relationship Testing: Executes all defined relationships (e.g.,
BelongsTo,HasMany,MorphTo) to verify that the related models load correctly and their foreign keys physically exist in the database!
🚀 Installation
You can install the package via Composer (development environment recommended):
composer require lucasmelocvl/laravel-model-unit-testing --dev
The package leverages Laravel package auto-discovery to register the service provider automatically.
📖 Usage
1. Generate Model Tests Automatically
Run the Artisan command to analyze all models and create or merge structural test suites:
php artisan models:generate-unit-tests --force
This command will:
- Discover all Eloquent models in your application.
- Scan the database to report any structural inconsistencies or missing tables.
- Automatically scaffold premium unit tests in
tests/Unit/Models/matching the subfolder structures of your models.
2. Run the Unit Tests
Execute the tests via PHPUnit:
vendor/bin/phpunit tests/Unit/Models
If memory limits are an issue due to extensive test suites, you can run them with a temporary limit override:
php -d memory_limit=-1 vendor/bin/phpunit tests/Unit/Models
🛠️ How it Works
Generated tests extend the package's robust BaseModelTest abstract class:
namespace Tests\Unit\Models; use App\Models\User; use Lucasmelocvl\LaravelModelUnitTesting\Abstracts\BaseModelTest; class UserTest extends BaseModelTest { protected function modelClass(): string { return \App\Models\User::class; } protected function expectedTable(): string { return 'users'; } protected function expectedPrimaryKey(): string { return 'id'; } protected function expectedIncrementing(): bool { return true; } protected function expectedKeyType(): string { return 'int'; } protected function expectedFillable(): array { return ['name', 'email', 'password']; } protected function expectedGuarded(): array { return []; } protected function expectedHidden(): array { return ['password', 'remember_token']; } protected function expectedCasts(): array { return ['email_verified_at' => 'datetime']; } protected function expectedDates(): array { return ['created_at', 'updated_at']; } protected function expectedAppends(): array { return []; } protected function expectedTraits(): array { return [ 'Illuminate\Database\Eloquent\SoftDeletes', ]; } protected function expectedRelationships(): array { return [ 'orders' => [ 'type' => 'HasMany', 'related' => 'App\Models\Order', 'foreignKey' => 'user_id', ], ]; } }
🤝 Contributing
We would love to have you help us improve laravel-model-unit-testing! Whether you've found a bug, want to add a feature, or have suggestions for better DB schema mappings, your contributions are highly welcome:
- Fork the repository on GitHub.
- Clone your fork locally.
- Create a descriptive feature branch (
git checkout -b feature/cool-new-assertion). - Write high-quality code and include test cases for new behaviors.
- Commit your changes and push them to your fork.
- Open a Pull Request detailing your changes, the rationale behind them, and how they benefit the community.
Feel free to open an issue on GitHub if you encounter bugs or want to share feedback! Let's build the safest and most robust testing ecosystem for Laravel developers together.
📄 License
This package is open-source software licensed under the MIT License.