Files
agent-unit-testing/docs/components/06-jobs-and-queues.md
T
Pham-Tan-Thien 2045c856e9 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>
2026-09-07 16:41:37 +07:00

112 lines
3.2 KiB
Markdown

# Component Guide: Queueable Jobs
Jobs xử lý các tác vụ nền không đồng bộ (Asynchronous Background Tasks) như gửi email hàng loạt, xử lý file nặng, đồng bộ dữ liệu.
---
## 1. Hai Mức Độ Kiểm Thử Cho Jobs
1. **Kiểm thử Dispatching (Job được đẩy vào hàng đợi đúng lúc không?)**:
- Dùng `Queue::fake()` trong Service/Controller test.
- Xác nhận `Queue::assertPushed(MyJob::class)`.
2. **Kiểm thử Thực Thi (Unit Test trực tiếp method `handle()` của Job)**:
- Đây chính là đối tượng của Unit Test Job.
- Khởi tạo trực tiếp đối tượng `$job = new ProcessPaymentJob(...)`.
- Inject mock dependencies vào method `handle()`.
- Kiểm tra xem Job có thực thi logic và gọi service đúng không.
- Kiểm tra method `failed(\Throwable $exception)` khi gặp sự cố.
---
## 2. Mã Mẫu Chuẩn: Job Unit Test
### Job Nguồn: `App\Jobs\SendWelcomeEmailJob`
```php
namespace App\Jobs;
use App\Contracts\MailerInterface;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class SendWelcomeEmailJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public int $tries = 3;
public function __construct(
public readonly User $user
) {}
public function handle(MailerInterface $mailer): void
{
$mailer->sendWelcome($this->user->email, $this->user->name);
}
public function failed(?\Throwable $exception): void
{
\Illuminate\Support\Facades\Log::error("Failed to send welcome email to user {$this->user->id}");
}
}
```
### Test Chuẩn: PHPUnit 10+
```php
namespace Tests\Unit\Jobs;
use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\Attributes\Test;
use Mockery;
use App\Jobs\SendWelcomeEmailJob;
use App\Contracts\MailerInterface;
use App\Models\User;
use Illuminate\Support\Facades\Log;
class SendWelcomeEmailJobTest extends TestCase
{
protected function tearDown(): void
{
Mockery::close();
parent::tearDown();
}
#[Test]
public function it_sends_welcome_email_when_handled(): void
{
// Arrange
$user = new User(['id' => 10, 'name' => 'Thien', 'email' => 'thien@example.com']);
$mailerMock = Mockery::mock(MailerInterface::class);
$mailerMock->shouldReceive('sendWelcome')
->once()
->with('thien@example.com', 'Thien');
$job = new SendWelcomeEmailJob($user);
// Act
$job->handle($mailerMock);
// Assert: Mockery tự động verify qua expectation ->once()
$this->assertTrue(true);
}
#[Test]
public function it_logs_error_when_job_fails(): void
{
// Arrange
$user = new User(['id' => 10, 'name' => 'Thien', 'email' => 'thien@example.com']);
$job = new SendWelcomeEmailJob($user);
Log::shouldReceive('error')
->once()
->with('Failed to send welcome email to user 10');
// Act
$job->failed(new \RuntimeException('SMTP Connection Timeout'));
}
}
```