【Laravel】Laravel 8で追加されたAssertメソッドを試してみた
前回の記事でLaravel8.xに導入されたAssertableJsonが紹介されていますが、今回も同じくLaravel8.xで利用できるAssertメソッドを2つ紹介したいと思います。
環境
- PHP: 8.1
- Laravel Framework 9.19.0
assertModelExists
$user = User::find(1);
$this->assertDatabaseHas('users', [
'id' => $user->getKey(),
]);
まずは、assertModelExistsからになります。上記はassertModelExistsが追加される以前に利用していたAssertメソッドでの書き方です。
assertModelExistsを使用すると下記のように書けます。
$user = User::find(1);
$this->assertModelExists($user);
内部的にはassertDatabaseHasを呼び出していて、指定したモデルがデータベースに存在することをアサートしています。
protected function assertModelExists($model)
{
return $this->assertDatabaseHas(
$model->getTable(),
[$model->getKeyName() => $model->getKey()],
$model->getConnectionName()
);
}
またassertDatabaseMissingに対応しているのはassertModelMissingになり、指定したモデルがデータベースに存在しないことをアサートします。
assertInvalid
次はバリデーションエラーに追加されたAssertメソッドのassertInvalidについてですが、その前に下記のようなJSONレスポンスが返されるユーザ登録APIのバリデーションについて考えます。
/**
* @param Request $request
* @return JsonResponse
* @throws \Throwable
*/
public function store(Request $request): JsonResponse
{
$request->validate(['name' => 'required']);
User::create(['name' => $request->get('name')]);
return response()->json(['message' => 'ユーザーを登録しました。']);
}
JSON形式のバリデーションエラーに対して指定のキーに指定のエラーメッセージが含まれるかをテストすると下記のように書けます。
$response = $this->json(
'post',
"api/user",
[]
);
// passします
$response->assertJsonValidationErrors(['name' => '名前は必ず指定してください。']);
しかしassertJsonValidationErrorsはバリデーションエラーがJSON形式で返される場合には利用できますが、セッションに一時保存される場合はassertSessionHasErrorsメソッドを利用する必要があります。
$response->assertSessionHasErrors(['name' => '名前は必ず指定してください。']);
このようにバリデーションエラーが含まれるレスポンスの形式によってassertJsonValidationErrorsとassertSessionHasErrorsの2つの異なるAsserメソッドを使い分ける必要がありましたが、標題のassertInvalidはどちらに対しても利用できるメソッドになります。
$response->assertInvalid(['name' => '名前は必ず指定してください。']);
余談ですが、assertInvalid追加コミットのコメントを眺めていた際、下記の利用例が目に飛び込んできて、バリデーションルールまでチェックできる便利メソッドなのかと驚きましたが、そんなことはありませんでした。。
$response->assertInvalid([
'name' => 'required',
]);
というのも下記のようにエラーメッセージの一部だけでも通るメソッドのため、"The name field is required."のような英語のエラーメッセージの一部("required")が記述されているだけで、決してバリデーションルールではなかったのです。
// ja
$response->assertInvalid(['name' => '指定して']);
// en
$response->assertInvalid([ 'name' => 'required']);
参考
https://laravel-news.com/laravel-8-56-0
https://laravel-news.com/laravel-8-61-0
最後に
今回は、Laravel 8.xで追加されたAssertメソッドについてご紹介しました。Assertメソッドは数多く存在していて、そうした既存のメソッドを改良し便利に利用できるようにした新たなメソッドも生まれ続けています。
よりシンプルにテストコードが書けるように今後もAssertメソッドの動向は注視していきたいですね。
以上となります。ありがとうございました。