> ## Documentation Index
> Fetch the complete documentation index at: https://inertiajs-vi.tuantq.online/llms.txt
> Use this file to discover all available pages before exploring further.

# Kiểm thử

Có nhiều cách khác nhau để kiểm thử một ứng dụng Inertia. Trang này cung cấp cái nhìn tổng quan nhanh về các công cụ hiện có.

## Kiểm thử end-to-end

Một cách phổ biến để kiểm thử các JavaScript page component là dùng công cụ end-to-end như [Cypress](https://www.cypress.io/) hoặc [Pest](https://pestphp.com). Đây là các công cụ tự động hóa trình duyệt, cho phép chạy những mô phỏng thực tế của ứng dụng ngay trong trình duyệt. Các test này thường chậm hơn; tuy nhiên, vì chúng kiểm thử ứng dụng ở cùng lớp mà người dùng cuối tương tác, chúng mang lại mức độ tin cậy cao rằng ứng dụng đang hoạt động đúng. Đồng thời, do test chạy trong trình duyệt, JavaScript của bạn cũng thực sự được thực thi và kiểm thử.

## Unit test phía client

Một cách khác để kiểm thử page component là dùng client-side unit testing framework như [Vitest](https://vitest.dev/), [Jest](https://jestjs.io/) hoặc [Mocha](https://mochajs.org/). Cách này cho phép kiểm thử JavaScript page component độc lập bằng Node.js.

## Kiểm thử endpoint

Ngoài kiểm thử page component JavaScript, bạn có thể cũng muốn kiểm thử các response Inertia do framework phía máy chủ trả về. Một cách phổ biến là dùng endpoint test, trong đó bạn gửi request đến ứng dụng và kiểm tra response. Laravel [cung cấp công cụ](https://laravel.com/docs/http-tests) để thực hiện loại test này.

Tuy nhiên, để quá trình này dễ dàng hơn nữa, adapter Laravel của Inertia cung cấp thêm các công cụ HTTP testing. Hãy xem một ví dụ.

```php theme={null}
use Inertia\Testing\AssertableInertia as Assert;

class PodcastsControllerTest extends TestCase
{
    public function test_can_view_podcast()
    {
        $this->get('/podcasts/41')
            ->assertInertia(fn (Assert $page) => $page
                ->component('Podcasts/Show')
                ->has('podcast', fn (Assert $page) => $page
                    ->where('id', $podcast->id)
                    ->where('subject', 'The Laravel Podcast')
                    ->where('description', 'The Laravel Podcast brings you Laravel and PHP development news and discussion.')
                    ->has('seasons', 4)
                    ->has('seasons.4.episodes', 21)
                    ->has('host', fn (Assert $page) => $page
                        ->where('id', 1)
                        ->where('name', 'Matt Stauffer')
                    )
                    ->has('subscribers', 7, fn (Assert $page) => $page
                        ->where('id', 2)
                        ->where('name', 'Claudio Dekker')
                        ->where('platform', 'Apple Podcasts')
                        ->etc()
                        ->missing('email')
                        ->missing('password')
                    )
                )
            );
    }
}
```

Như ví dụ trên, bạn có thể dùng các phương thức assertion này để kiểm tra nội dung dữ liệu được truyền vào response Inertia. Ngoài ra, bạn có thể assert dữ liệu mảng có độ dài nhất định cũng như giới hạn phạm vi assertion.

Bạn có thể dùng phương thức `inertiaProps` để lấy các prop được trả về trong response. Có thể truyền một key để lấy thuộc tính cụ thể; các thuộc tính lồng nhau được hỗ trợ bằng ký pháp "dot".

```php theme={null}
$response = $this->get('/podcasts/41');

// Returns all props...
$response->inertiaProps();

// Returns a specific prop...
$response->inertiaProps('podcast');

// Returns a nested prop using "dot" notation...
$response->inertiaProps('podcast.id');
```

Hãy xem chi tiết phương thức `assertInertia` và các assertion có sẵn. Trước tiên, để xác nhận response Inertia có một thuộc tính, bạn có thể dùng phương thức `has`. Có thể xem phương thức này tương tự hàm `isset` của PHP.

```php theme={null}
$response->assertInertia(fn (Assert $page) => $page
    // Checking if a root-level property has 7 items...
    ->has('podcasts', 7)

    // Checking nested properties using "dot" notation...
    ->has('podcast.subscribers', 7)
);
```

Để assertion một Inertia property có số phần tử cụ thể, bạn có thể truyền expected size làm đối số thứ hai cho phương thức `has`.

```php theme={null}
$response->assertInertia(fn (Assert $page) => $page
    // Checking if a root-level property has 7 items...
    ->has('podcasts', 7)

    // Checking nested properties using "dot" notation...
    ->has('podcast.subscribers', 7)
);
```

Phương thức `has` cũng có thể được dùng để scope các property, giúp giảm lặp khi assert trên các property lồng nhau.

```php theme={null}
$response->assertInertia(fn (Assert $page) => $page
    // Creating a single-level property scope...
    ->has('message', fn (Assert $page) => $page
        // We can now continue chaining methods...
        ->has('subject')
        ->has('comments', 5)

        // And can even create a deeper scope using "dot" notation...
        ->has('comments.0', fn (Assert $page) => $page
            ->has('body')
            ->has('files', 1)
            ->has('files.0', fn (Assert $page) => $page
                ->has('url')
            )
        )
    )
);
```

Khi scope vào các property Inertia là mảng hoặc collection, bạn cũng có thể assert số lượng item cụ thể đồng thời scope vào item đầu tiên.

```php theme={null}
$response->assertInertia(fn (Assert $page) => $page
    // Assert that there are 5 comments and automatically scope into the first comment...
    ->has('comments', 5, fn (Assert $page) => $page
        ->has('body')
        // ...
    )
);
```

Để assert một property Inertia có giá trị mong đợi, bạn có thể dùng assertion `where`.

```php theme={null}
$response->assertInertia(fn (Assert $page) => $page
    ->has('message', fn (Assert $page) => $page
        // Assert that the subject prop matches the given message...
        ->where('subject', 'This is an example message')

        // Or, assert against deeply nested values...
        ->where('comments.0.files.0.name', 'example-attachment.pdf')
    )
);
```

Các phương thức testing của Inertia sẽ tự động fail nếu bạn chưa tương tác với ít nhất một prop trong một scope. Điều này nhìn chung hữu ích, nhưng đôi khi bạn làm việc với dữ liệu không ổn định (chẳng hạn từ feed bên ngoài), hoặc có dữ liệu bạn thực sự không muốn tương tác để giữ test đơn giản. Trong các trường hợp đó, hãy dùng phương thức `etc`.

```php theme={null}
$response->assertInertia(fn (Assert $page) => $page
    ->has('message', fn (Assert $page) => $page
        ->has('subject')
        ->has('comments')
        ->etc()
    )
);
```

Phương thức `missing` hoàn toàn đối lập với `has`, dùng để đảm bảo property không tồn tại. Phương thức này kết hợp rất tốt với `etc`.

```php theme={null}
$response->assertInertia(fn (Assert $page) => $page
    ->has('message', fn (Assert $page) => $page
        ->has('subject')
        ->missing('published_at')
        ->etc()
    )
);
```

### Kiểm thử partial reload

Bạn có thể dùng `reloadOnly` và `reloadExcept` để kiểm thử cách ứng dụng phản hồi với [partial reload](/v3/data-props/partial-reloads). Các phương thức thực hiện follow-up request và cho phép assertion trên response.

```php theme={null}
$response->assertInertia(fn (Assert $page) => $page
    ->has('orders')
    ->missing('statuses')
    ->reloadOnly('statuses', fn (Assert $reload) => $reload
        ->missing('orders')
        ->has('statuses', 5)
    )
);
```

Thay vì truyền một prop duy nhất dưới dạng chuỗi, bạn cũng có thể truyền một mảng prop vào `reloadOnly` hoặc `reloadExcept`.

### Kiểm thử deferred props

Bạn có thể dùng `loadDeferredProps` để kiểm thử cách ứng dụng phản hồi với [deferred props](/v3/data-props/deferred-props). Phương thức thực hiện follow-up request để tải deferred props và cho phép assertion trên response.

```php theme={null}
$response->assertInertia(fn (Assert $page) => $page
    ->has('users')
    ->has('roles')
    ->missing('permissions') // Deferred prop not in initial response
    ->loadDeferredProps(fn (Assert $reload) => $reload
        ->has('permissions')
        ->where('permissions.0.name', 'edit users')
    )
);
```

Bạn cũng có thể tải các nhóm deferred prop cụ thể bằng cách truyền tên nhóm làm đối số đầu tiên cho phương thức `loadDeferredProps`.

```php theme={null}
$response->assertInertia(fn (Assert $page) => $page
    ->has('users')
    ->missing('teams')
    ->missing('projects')
    ->loadDeferredProps('attributes', fn (Assert $reload) => $reload
        ->has('teams', 5)
        ->has('projects')
        ->missing('permissions') // Different group
    )
);
```

Thay vì truyền một nhóm duy nhất dưới dạng chuỗi, bạn cũng có thể truyền một mảng nhóm vào `loadDeferredProps`.

```php theme={null}
$response->assertInertia(fn (Assert $page) => $page
    ->loadDeferredProps(['default', 'attributes'], fn (Assert $reload) => $reload
        ->has('permissions')
        ->has('teams')
        ->has('projects')
    )
);
```

### Kiểm thử flash data

Bạn có thể dùng `hasFlash` và `missingFlash` để kiểm thử [flash data](/v3/data-props/flash-data) trong Inertia response.

```php theme={null}
$response->assertInertia(fn (Assert $page) => $page
    // Assert flash data exists...
    ->hasFlash('message')

    // Assert flash data has a specific value...
    ->hasFlash('message', 'Item saved!')

    // Nested values are supported using "dot" notation...
    ->hasFlash('notification.type', 'success')

    // Assert flash data does not exist...
    ->missingFlash('error')
);
```

#### Redirect response

Các phương thức `hasFlash` và `missingFlash` ở trên chỉ hoạt động với response của Inertia page đã render. Với redirect response, bạn có thể dùng trực tiếp `assertInertiaFlash` và `assertInertiaFlashMissing` trên test response để assertion dữ liệu flash trong session.

```php theme={null}
$response = $this->post('/users');

$response->assertRedirect('/dashboard')
    ->assertInertiaFlash('message')
    ->assertInertiaFlash('message', 'User created!')
    ->assertInertiaFlash('notification.type', 'success')
    ->assertInertiaFlashMissing('error');
```

## Tắt SSR trong khi test

Ứng dụng có thể [bật SSR](/v3/advanced/server-side-rendering) cho development và production nhưng không cần trong testing. Bạn có thể đặt `INERTIA_SSR_ENABLED` thành `false` trong `phpunit.xml` để ngăn Laravel adapter dispatch SSR request.

```xml theme={null}
<env name="INERTIA_SSR_ENABLED" value="false" />
```

Ngoài ra, có thể dùng phương thức `Inertia::disableSsr()` trong test base class.

```php theme={null}
use Inertia\Inertia;

abstract class TestCase extends BaseTestCase
{
    protected function setUp(): void
    {
        parent::setUp();

        Inertia::disableSsr();
    }
}
```

Có thể truyền boolean hoặc closure để tắt SSR theo điều kiện. Việc này thường được gọi từ service provider.

```php theme={null}
// Evaluated immediately...
Inertia::disableSsr(app()->runningUnitTests());

// Evaluated lazily...
Inertia::disableSsr(fn () => app()->runningUnitTests());
```

***

## Tài liệu chính thức

Bài dịch này được đối chiếu từ [tài liệu Inertia.js v3 chính thức](https://inertiajs.com/docs/v3/advanced/testing). Nếu có khác biệt do phiên bản hoặc cập nhật mới, hãy ưu tiên tài liệu chính thức làm nguồn tham chiếu.
