feat: complete Smartgift AI Laravel unit testing toolkit
- Add 10 core testing guides (setup, AAA principles, PHPUnit/Pest, mocking, anti-patterns, PHP 8.4+, debugging, data factories, advanced edge cases) - Add 13 component testing guides covering all Laravel layers - Add standard templates for PHPUnit 10/11 and Pest v2/v3 including ArchitectureTest - Add Docker smart test runner, dependency installer, and CI/CD templates (GitHub Actions, GitLab CI) - Add 4 Claude Code skills (laravel-test-setup, laravel-unit-test with --all mode, laravel-test-review, laravel-mock-helper) - Add single unified installer script (sg-install-unit-testing.sh) with global support, CLI runners, and 1-click updater (sg-test-update) - Add comprehensive documentation (README.md, USAGE-GUIDE.md) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
# Component Guide: Artisan Console Commands
|
||||
|
||||
Artisan Commands xử lý các công việc chạy từ dòng lệnh (CLI), cron jobs, và lệnh bảo trì hệ thống.
|
||||
|
||||
---
|
||||
|
||||
## 1. Bản Chất Kiểm Thử Console Command
|
||||
|
||||
Khi test một Artisan Command, cần kiểm tra:
|
||||
1. **Exit Code**: Trả về `Command::SUCCESS` (0) khi hoàn thành, hoặc `Command::FAILURE` (1) / `Command::INVALID` (2) khi có lỗi.
|
||||
2. **Output trên màn hình**: Kiểm tra dòng thông báo in ra bằng `expectsOutput()`, `doesntExpectOutput()`, `expectsTable()`.
|
||||
3. **User Interaction**: Kiểm tra câu hỏi tương tác như `expectsConfirmation()`, `expectsQuestion()`, `expectsChoice()`.
|
||||
4. **Service Execution**: Đảm bảo Command gọi đúng Service xử lý logic ngầm bên dưới.
|
||||
|
||||
---
|
||||
|
||||
## 2. Mã Mẫu Chuẩn: Console Command Test
|
||||
|
||||
### Command Nguồn: `App\Console\Commands\PruneOldLogsCommand`
|
||||
```php
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use App\Services\LogCleanupService;
|
||||
|
||||
class PruneOldLogsCommand extends Command
|
||||
{
|
||||
protected $signature = 'logs:prune {--days=30 : Số ngày lưu log cũ} {--force : Thực thi mà không hỏi lại}';
|
||||
protected $description = 'Xóa các file log cũ hơn số ngày quy định';
|
||||
|
||||
public function handle(LogCleanupService $cleanupService): int
|
||||
{
|
||||
$days = (int) $this->option('days');
|
||||
|
||||
if ($days <= 0) {
|
||||
$this->error('Số ngày phải lớn hơn 0.');
|
||||
return self::INVALID;
|
||||
}
|
||||
|
||||
if (!$this->option('force') && !$this->confirm("Bạn có chắc chắn muốn xóa log cũ hơn {$days} ngày?")) {
|
||||
$this->info('Đã hủy thao tác.');
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
$deletedCount = $cleanupService->deleteLogsOlderThan($days);
|
||||
$this->info("Đã dọn dẹp thành công {$deletedCount} file log.");
|
||||
|
||||
return self::SUCCESS;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Test Chuẩn: PHPUnit 10+
|
||||
```php
|
||||
namespace Tests\Unit\Console\Commands;
|
||||
|
||||
use Tests\TestCase;
|
||||
use PHPUnit\Framework\Attributes\Test;
|
||||
use Mockery;
|
||||
use App\Services\LogCleanupService;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class PruneOldLogsCommandTest extends TestCase
|
||||
{
|
||||
#[Test]
|
||||
public function it_fails_when_days_option_is_zero_or_negative(): void
|
||||
{
|
||||
$this->artisan('logs:prune --days=0')
|
||||
->expectsOutput('Số ngày phải lớn hơn 0.')
|
||||
->assertExitCode(Command::INVALID);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function it_cancels_pruning_when_user_declines_confirmation(): void
|
||||
{
|
||||
$this->artisan('logs:prune --days=15')
|
||||
->expectsConfirmation('Bạn có chắc chắn muốn xóa log cũ hơn 15 ngày?', 'no')
|
||||
->expectsOutput('Đã hủy thao tác.')
|
||||
->assertExitCode(Command::SUCCESS);
|
||||
}
|
||||
|
||||
#[Test]
|
||||
public function it_prunes_logs_successfully_when_forced(): void
|
||||
{
|
||||
// Mock service
|
||||
$cleanupServiceMock = Mockery::mock(LogCleanupService::class);
|
||||
$cleanupServiceMock->shouldReceive('deleteLogsOlderThan')
|
||||
->once()
|
||||
->with(30)
|
||||
->andReturn(12);
|
||||
|
||||
$this->app->instance(LogCleanupService::class, $cleanupServiceMock);
|
||||
|
||||
$this->artisan('logs:prune --days=30 --force')
|
||||
->expectsOutput('Đã dọn dẹp thành công 12 file log.')
|
||||
->assertExitCode(Command::SUCCESS);
|
||||
}
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user