カスタムの期待
Pest の期待 API はデフォルトで強力ですが、テスト間で同じ期待を繰り返し記述する必要がある場合があります。そのような場合、特定の要件を満たすカスタムの期待を作成すると非常に役立ちます。
カスタムの期待は通常 `tests/Pest.php` ファイルで定義されますが、よりメンテナンス性を高めるために `tests/Expectations.php` ファイルで個別に整理することもできます。Pest でカスタムの期待を作成するには、期待値を指定せずに `expect()` 関数に `extend()` メソッドを連鎖させます。
たとえば、数値ユーティリティライブラリをテストしていて、数値が特定の範囲内にあることを頻繁にアサートする必要があるとします。この場合、`toBeWithinRange()` という名前のカスタムの期待を作成する可能性があります
1// Pest.php or Expectations.php... 2expect()->extend('toBeWithinRange', function (int $min, int $max) { 3 return $this->toBeGreaterThanOrEqual($min) 4 ->toBeLessThanOrEqual($max); 5}); 6 7// Tests/Unit/ExampleTest.php 8test('numeric ranges', function () { 9 expect(100)->toBeWithinRange(90, 110);10});
ユーザーは通常、`toBeWithinRange()` の例のようにカスタムの期待の中で Pest の組み込みの期待を使用しますが、独自のカスタムの期待ロジックを実行するために期待値に直接アクセスする必要がある場合があります。そのような場合、`expect($value)` に渡された期待値には、`$this->value` プロパティを使用してアクセスできます。
1expect()->extend('toBeWithinRange', function (int $min, int $max) {2 echo $this->value; // 1003});
もちろん、ユーザーにはカスタムの期待と一緒に期待を「連鎖」させる機能を持たせたいと思うでしょう。この機能を実現するには、カスタムの期待に `return $this` ステートメントが含まれるようにします。
1// Pest.php or Expectations.php... 2expect()->extend('toBeWithinRange', function (int $min, int $max) { 3 // Assertions based on `$this->value` and the given arguments... 4 5 return $this; // Return this, so another expectations can chain this one... 6}); 7 8// Tests/Unit/ExampleTest.php 9test('numeric ranges', function () {10 expect(100)11 ->toBeInt()12 ->toBeWithinRange(90, 110)13 ->to...14});
期待のインターセプト
高度な手法と見なされますが、`intercept()` メソッドを使用して独自のインプリメンテーションで既存の期待をオーバーライドできます。このメソッドを使用すると、期待値が指定されたタイプの値である場合、既存の期待が完全に置き換えられます。たとえば、`Illuminate\Database\Eloquent\Model` タイプの 2 つのオブジェクトが同じ `id` を持っているかどうかを確認するために、`toBe()` 期待を置き換えることができます。
1use Illuminate\Database\Eloquent\Model; 2use App\Models\User; 3 4// tests/Pest.php or tests/Expectations.php 5expect()->intercept('toBe', Model::class, function(Model $expected) { 6 expect($this->value->id)->toBe($expected->id); 7}); 8 9// tests/Feature/ExampleTest.php10test('models', function () {11 $userA = User::find(1);12 $userB = User::find(1);13 14 expect($userA)->toBe($userB);15});
`intercept()` メソッドの 2 番目の引数として文字列タイプを渡す代わりに、クロージャを渡すこともできます。これにより、コアの期待をオーバーライドするかどうかを判断するために呼び出されます。
1expect()->intercept('toBe', fn (mixed $value) => is_string($value), function (string $expected, bool $ignoreCase = false) {2 if ($ignoreCase) {3 assertEqualsIgnoringCase($expected, $this->value);4 } else {5 assertSame($expected, $this->value);6 }7});
期待のパイプライン
Pest の組み込みの期待の 1 つを実行しつつ、特定の条件下でカスタマイズされた期待のロジックを含めたい場合があります。その場合は、pipe()
メソッドを使用できます。たとえば、指定された値が Eloquent モデルの場合に toBe()
期待の動作をカスタマイズしたい場合などです。
1use Illuminate\Database\Eloquent\Model; 2use App\Models\User; 3 4expect()->pipe('toBe', function (Closure $next, mixed $expected) { 5 if ($this->value instanceof Model) { 6 return expect($this->value->id)->toBe($expected->id); 7 } 8 9 return $next(); // Run to the original, built-in expectation...10});
示したように、テストが予想どおりに動作していることを検証するためのロジックを複製する必要がなくなるため、カスタムの期待を作成することによりコードを大幅に簡素化できます。次の章では、Pest が提供する追加の CLI オプションをご紹介します。 CLI API リファレンス