Files
agent-unit-testing/docs/06-future-php84-laravel-latest.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

5.8 KiB

06. Hướng Dẫn Nâng Cao: PHP 8.4+ & Laravel 12 / 13 (Latest & Future-Proof)

Tài liệu này chuẩn bị đầy đủ các kỹ thuật kiểm thử cho các phiên bản PHP và Laravel mới nhất, bao gồm PHP 8.4, Laravel 12 & 13, PHPUnit 11/12 và Pest PHP v3.


1. Kiểm Thử Các Tính Năng Mới Của PHP 8.4

PHP 8.4 giới thiệu nhiều thay đổi mang tính cách mạng trong cú pháp lập trình hướng đối tượng. Unit Test cần thích ứng chính xác:

A. Property Hooks (get / set)

Thay vì viết getter/setter truyền thống hoặc Eloquent Accessor cũ, PHP 8.4 cho phép định nghĩa hooks ngay trên thuộc tính:

// DTO hoặc Model trong PHP 8.4
class UserProfile
{
    public string $firstName;
    public string $lastName;

    // Property Hook tự động tính toán
    public string $fullName {
        get => trim("{$this->firstName} {$this->lastName}");
    }

    // Property Hook kiểm soát gán giá trị
    public string $email {
        set {
            if (!filter_var($value, FILTER_VALIDATE_EMAIL)) {
                throw new \InvalidArgumentException('Email không hợp lệ');
            }
            $this->email = strtolower($value);
        }
    }
}

Cách viết Unit Test:

#[Test]
public function it_calculates_full_name_via_property_hook(): void
{
    $profile = new UserProfile();
    $profile->firstName = 'Thien';
    $profile->lastName = 'Phan';

    // Kiểm thử get hook
    $this->assertSame('Thien Phan', $profile->fullName);
}

#[Test]
public function it_throws_exception_when_setting_invalid_email_hook(): void
{
    $profile = new UserProfile();

    $this->expectException(\InvalidArgumentException::class);
    // Kiểm thử set hook
    $profile->email = 'invalid-email-format';
}

B. Asymmetric Visibility (public private(set))

PHP 8.4 cho phép thuộc tính có quyền đọc công khai nhưng chỉ được sửa từ bên trong class:

class BankAccount
{
    // Đọc public từ ngoài, nhưng chỉ private method được set
    public private(set) int $balance = 0;

    public function deposit(int $amount): void
    {
        if ($amount <= 0) {
            throw new \InvalidArgumentException('Số tiền nạp phải > 0');
        }
        $this->balance += $amount;
    }
}

Cách viết Unit Test:

#[Test]
public function it_updates_balance_via_public_api_and_allows_public_reading(): void
{
    $account = new BankAccount();
    
    // Đọc trạng thái ban đầu
    $this->assertSame(0, $account->balance);

    // Kích hoạt method hợp lệ
    $account->deposit(500_000);
    $this->assertSame(500_000, $account->balance);

    // Cố tình ghi đè từ ngoài sẽ gây Error (PHP Fatal Error)
    // Unit test tập trung xác nhận method nội bộ thay đổi đúng giá trị
}

C. Hàm Array Mới (array_find, array_any, array_all)

Kiểm thử các business logic sử dụng các hàm tiện ích mảng mới của PHP 8.4.


2. Kiểm Thử Kiến Trúc Laravel Hiện Đại (Laravel 11, 12, 13)

A. Concurrency API (Concurrency::fake())

Từ Laravel 11 và tiếp tục hoàn thiện trên Laravel 12/13, Laravel cung cấp Facade Concurrency để chạy các tác vụ song song:

// Trong Service
public function fetchDashboardData(): array
{
    return Concurrency::run([
        fn () => $this->userService->getStats(),
        fn () => $this->orderService->getRevenue(),
    ]);
}

Cách viết Unit Test:

use Illuminate\Support\Facades\Concurrency;

#[Test]
public function it_executes_concurrent_tasks_correctly(): void
{
    // Giả lập Concurrency để chạy tuần tự trong lúc test
    Concurrency::fake();

    $dashboardData = $dashboardService->fetchDashboardData();

    $this->assertCount(2, $dashboardData);
}

B. Context API (Context::fake())

Laravel Context cho phép theo dõi metadata xuyên suốt vòng đời request và background jobs:

use Illuminate\Support\Facades\Context;

#[Test]
public function it_attaches_trace_id_to_context(): void
{
    $middleware = new TraceContextMiddleware();
    $request = Request::create('/api/orders', 'GET');
    $request->headers->set('X-Trace-ID', 'trace-xyz-123');

    $middleware->handle($request, fn () => response('OK'));

    $this->assertSame('trace-xyz-123', Context::get('trace_id'));
}

3. Pest PHP v3: Architecture Testing (arch())

Trong các dự án Laravel 11/12/13 hiện đại dùng Pest v3, ngoài việc test từng method, chúng ta có thể viết Architectural Tests để kiểm soát toàn bộ cấu trúc code:

// tests/Unit/ArchitectureTest.php

describe('Architecture Rules', function () {
    test('Controllers do not directly use Models (must use Services/Actions)')
        ->expect('App\Http\Controllers')
        ->not->toUse('App\Models')
        ->ignoring('App\Http\Controllers\Auth');

    test('Services must be readonly or final')
        ->expect('App\Services')
        ->toBeFinal();

    test('All Value Objects must be immutable')
        ->expect('App\ValueObjects')
        ->toBeReadonly();

    test('No debugging functions left in code')
        ->expect(['dd', 'dump', 'ray', 'var_dump'])
        ->not->toBeUsed();
});

4. Tương Thích PHPUnit 11 & 12

  1. Loại bỏ hoàn toàn DocBlock: PHPUnit 11+ deprecate và loại bỏ chú thích dạng @test, @dataProvider. Bắt buộc 100% sử dụng:
    • #[PHPUnit\Framework\Attributes\Test]
    • #[PHPUnit\Framework\Attributes\DataProvider('providerMethod')]
    • #[PHPUnit\Framework\Attributes\TestDox('Mô tả tiếng Việt dễ đọc')]
  2. Event-driven Internal System: PHPUnit 11 quản lý vòng đời test hoàn toàn bằng sự kiện, giúp execution nhanh hơn và đo lường chính xác hơn.