# Component Guide: Mailables & Notifications Kiểm thử gửi Mail và Notification trong Laravel gồm kiểm tra các kênh gửi (`via`), nội dung (`toMail`, `toArray`) và các biến dữ liệu gán vào view. --- ## 1. Bản Chất Kiểm Thử Mailable & Notification 1. **Mailable Unit Test**: - Kiểm tra `subject` (tiêu đề email). - Kiểm tra người nhận (`to`), người gửi (`from`). - Kiểm tra file đính kèm (`attachments`). - Kiểm tra xem view template có render đúng nội dung với data truyền vào không. 2. **Notification Unit Test**: - Kiểm tra method `via($notifiable)`: Trả về đúng mảng các kênh `['mail', 'database']`. - Kiểm tra method `toMail($notifiable)`: Đối tượng `MailMessage` có chứa đúng tiêu đề, lời chào và URL nút bấm. - Kiểm tra method `toArray($notifiable)`: Cấu trúc mảng lưu trữ vào bảng notifications. --- ## 2. Mã Mẫu Chuẩn: Notification Unit Test ### Notification Nguồn: `App\Notifications\InvoicePaidNotification` ```php namespace App\Notifications; use App\Models\Invoice; use Illuminate\Bus\Queueable; use Illuminate\Notifications\Messages\MailMessage; use Illuminate\Notifications\Notification; class InvoicePaidNotification extends Notification { use Queueable; public function __construct( public readonly Invoice $invoice ) {} public function via(object $notifiable): array { return ['mail', 'database']; } public function toMail(object $notifiable): MailMessage { return (new MailMessage) ->subject("Hóa đơn #{$this->invoice->number} đã được thanh toán") ->greeting("Xin chào {$notifiable->name},") ->line("Cảm ơn bạn đã thanh toán số tiền: {$this->invoice->amount} VND.") ->action('Xem chi tiết hóa đơn', url("/invoices/{$this->invoice->id}")); } public function toArray(object $notifiable): array { return [ 'invoice_id' => $this->invoice->id, 'amount' => $this->invoice->amount, 'paid_at' => now()->toIso8601String(), ]; } } ``` ### Test Chuẩn: PHPUnit 10+ ```php namespace Tests\Unit\Notifications; use PHPUnit\Framework\TestCase; use PHPUnit\Framework\Attributes\Test; use App\Notifications\InvoicePaidNotification; use App\Models\Invoice; use App\Models\User; class InvoicePaidNotificationTest extends TestCase { #[Test] public function it_defines_correct_notification_channels(): void { $invoice = new Invoice(['id' => 1, 'number' => 'INV-2026', 'amount' => 500000]); $notification = new InvoicePaidNotification($invoice); $user = new User(['id' => 10, 'name' => 'Thien']); $channels = $notification->via($user); $this->assertSame(['mail', 'database'], $channels); } #[Test] public function it_builds_correct_mail_message(): void { $invoice = new Invoice(['id' => 99, 'number' => 'INV-99', 'amount' => 100000]); $notification = new InvoicePaidNotification($invoice); $user = new User(['id' => 10, 'name' => 'Thien']); $mailMessage = $notification->toMail($user); $this->assertSame('Hóa đơn #INV-99 đã được thanh toán', $mailMessage->subject); $this->assertSame('Xin chào Thien,', $mailMessage->greeting); $this->assertSame('Xem chi tiết hóa đơn', $mailMessage->actionText); $this->assertStringContainsString('/invoices/99', $mailMessage->actionUrl); } #[Test] public function it_builds_correct_database_array_payload(): void { $invoice = new Invoice(['id' => 55, 'number' => 'INV-55', 'amount' => 250000]); $notification = new InvoicePaidNotification($invoice); $user = new User(['id' => 10, 'name' => 'Thien']); $data = $notification->toArray($user); $this->assertSame(55, $data['invoice_id']); $this->assertSame(250000, $data['amount']); $this->assertArrayHasKey('paid_at', $data); } } ```