测试

有许多不同的方法可以测试 Inertia 应用程序。本页提供对可用工具的快速概述。

端到端测试

测试 JavaScript 页面组件的一种流行方法是使用端到端测试工具,例如 CypressLaravel Dusk。这些是浏览器自动化工具,允许您在浏览器中运行应用程序的真实模拟。这些测试以速度较慢而闻名;但是,由于它们在与最终用户相同的层级上测试您的应用程序,因此它们可以提供很多信心,证明您的应用程序正常工作。而且,由于这些测试是在浏览器中运行的,因此您的 JavaScript 代码也会被实际执行和测试。

客户端单元测试

测试页面组件的另一种方法是使用客户端单元测试框架,例如 JestMocha。这种方法允许您使用 Node.js 隔离测试 JavaScript 页面组件。

端点测试

除了测试 JavaScript 页面组件之外,您可能还想测试服务器端框架返回的 Inertia 响应。执行此操作的一种流行方法是使用端点测试,您在其中向应用程序发出请求并检查响应。Laravel 提供工具 用于执行这些类型的测试。

但是,为了使此过程更轻松,Inertia 的 Laravel 适配器提供了额外的 HTTP 测试工具。让我们看一个例子。

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')
                    )
                )
            );
    }
}

如上面的示例所示,您可以使用这些断言方法来断言 Inertia 响应提供的数据内容。此外,您可以断言数组数据具有给定的长度,以及对断言进行范围限定。

让我们详细了解可用的断言。首先,要断言 Inertia 响应具有属性,您可以使用 has 方法。您可以将此方法视为类似于 PHP 的 isset 函数。

$response->assertInertia(fn (Assert $page) => $page
    // Checking a root-level property...
    ->has('podcast')

    // Checking nested properties using "dot" notation...
    ->has('podcast.id')
);

要断言 Inertia 属性具有指定数量的项目,您可以将预期的尺寸作为第二个参数提供给 has 方法。

$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)
);

has 方法也可以用于对属性进行范围限定,以便在断言嵌套属性时减少重复。

$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')
            )
        )
    )
);

当对作为数组或集合的 Inertia 属性进行范围限定时,除了对第一个项目进行范围限定之外,您还可以断言存在指定数量的项目。

$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')
        // ...
    )
);

要断言 Inertia 属性具有预期的值,您可以使用 where 断言。

$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')
    )
);

Inertia 的测试方法会在您没有与范围内的至少一个道具进行交互时自动失败。虽然这通常很有用,但您可能会遇到处理不可靠数据(例如来自外部提要的数据)的情况,或者处理您真的不想与之交互以保持测试简单的数据的情况。对于这些情况,etc 方法存在。

$response->assertInertia(fn (Assert $page) => $page
    ->has('message', fn (Assert $page) => $page
        ->has('subject')
        ->has('comments')
        ->etc()
    )
);

missing 方法与 has 方法完全相反,确保属性不存在。此方法是 etc 方法的绝佳伴侣。

$response->assertInertia(fn (Assert $page) => $page
    ->has('message', fn (Assert $page) => $page
        ->has('subject')
        ->missing('published_at')
        ->etc()
    )
);