Laravel & Inertiaのテストでresource/js以外をテスト対象にする方法
背景
LaravelとInertia.jsでSPAを作成しています。
ユーザー画面と管理画面でディレクトリを分けています。
ユーザー画面
resources/js/Pages
配下にページを作成しています。
- resources/js/Pages/User/Show.vueを作成済
コントローラー
use Inertia\Inertia;
class UserController extends Controller
{
public function show(User $user)
{
return Inertia::render('User/Show', [
'user' => $user
]);
}
}
ルーティング
Route::get('/show', [UserController::class, 'show'])->name('show');
管理画面
resources/js-admin/Pages
配下にページを作成しています。
- resources/js-admin/Pages/Admin/Show.vueを作成済
コントローラー
use Inertia\Inertia;
class AdminController extends Controller
{
public function show(User $admin)
{
return Inertia::render('Admin/Show', [
'admin' => $admin
]);
}
}
ルーティング
Route::get('/admin/show', [AdminController::class, 'show'])->name('admin.show');
テストを書いていく
テストには、Pestを利用しています。
ユーザー画面
test('ログインユーザーの場合、ユーザー画面に遷移できること', function () {
// ユーザー作成
$user = User::factory()->create();
// 作成したユーザーをログインさせて、UserControllerのshowメソッド呼び出し
$response = $this->actingAs($user)->get(route('show'));
$response->assertOk();
$response->assertInertia(function (Assert $assert) {
$assert->component('User/Show');
});
});
上記のテストを実行すると問題なく成功します。
管理画面
では、以下の管理画面のテストは成功するでしょうか?
test('管理者の場合、管理画面に遷移できること', function () {
// 管理者作成
$superAdmin = User::factory()->superAdmin()->create();
// 作成した管理者をログインさせて、AdminControllerのshowメソッド呼び出し
$response = $this->actingAs($superAdmin)->get(route('admin.show'));
$response->assertOk();
$response->assertInertia(function (Assert $assert) {
$assert->component('Admin/Show');
});
});
↑このテストは失敗します。
Inertia page component file [Admin/Show] does not exist.
テスト失敗の原因
なぜ同じようなテストを書いても、前者は成功し、後者は失敗するのでしょうか?
その原因は、Inertiaのconfigにありました。
vendor/inertiajs/inertia-laravel/config/inertia.php
を見てみましょう。
<?php
return [
/*
|--------------------------------------------------------------------------
| Server Side Rendering
|--------------------------------------------------------------------------
|
| These options configures if and how Inertia uses Server Side Rendering
| to pre-render the initial visits made to your application's pages.
|
| Do note that enabling these options will NOT automatically make SSR work,
| as a separate rendering service needs to be available. To learn more,
| please visit https://inertiajs.com/server-side-rendering
|
*/
'ssr' => [
'enabled' => false,
'url' => 'http://127.0.0.1:13714/render',
],
/*
|--------------------------------------------------------------------------
| Testing
|--------------------------------------------------------------------------
|
| The values described here are used to locate Inertia components on the
| filesystem. For instance, when using `assertInertia`, the assertion
| attempts to locate the component as a file relative to any of the
| paths AND with any of the extensions specified here.
|
*/
'testing' => [
'ensure_pages_exist' => true,
'page_paths' => [
resource_path('js/Pages'),
],
'page_extensions' => [
'js',
'jsx',
'svelte',
'ts',
'tsx',
'vue',
],
],
];
重要なのは、以下の部分です。
'testing' => [
// 'ensure_pages_exist' => true,
'page_paths' => [
resource_path('js/Pages'),
],
//'page_extensions' => [
//
// 'js',
// 'jsx',
// 'svelte',
// 'ts',
// 'tsx',
// 'vue',
// ],
],
そうです。テスト実行時にデフォルトで読み込まれるパスは、resources/js/Pages
のみなのです。
管理画面のページを管理しているディレクトリは、どこか思い出してみましょう。。
...
...
resources/js-admin/Pages !?
そうなんです。resources/js-admin/Pages
なんです。
本来だと、resoruces/js-admin/Pages/Admin/Show.vue
を探して欲しいところを、Inertia君はresources/js/Pages/Admin/Show.vue
を探していました。
これが原因です。
解決策
この問題の解決策は非常にシンプルです。
テスト中だけ一時的にpage_paths
を書き換えてやれば、OKです。
テストに下記のように1行追加してください。
test('管理者の場合、管理画面に遷移できること', function () {
// パス書き換え
+ Config::set('inertia.testing.page_paths',[resource_path('js-admin/Pages')]);
// 管理者作成
$superAdmin = User::factory()->superAdmin()->create();
// 作成した管理者をログインさせて、AdminControllerのshowメソッド呼び出し
$response = $this->actingAs($superAdmin)->get(route('admin.show'));
$response->assertOk();
$response->assertInertia(function (Assert $assert) {
$assert->component('Admin/Show');
});
});
Config::set('inertia.testing.page_paths',[resource_path('js-admin/Pages')]);
↑この記述をすることで、resources/js-admin/Pages
配下のAdmin/Show.vue
を検索してくれるようになります。
そして、テストも成功します。
めでたし、めでたし。
Discussion