LoginSignup
0
0

More than 1 year has passed since last update.

【PHPUnit】よりベターなテストの仕方

Last updated at Posted at 2022-06-30

環境

Laravel v9.5.1 (PHP v8.1.3)

前提条件

PostモデルにUserで検索するscopeByUser()を定義している。
Unitテストでこのメソッドをテストしたい。

public function scopeByUser($query, User $user): Builder
{
  return $query->where('user_id', $user->id);
}

Before

  /**
   * scopeByUser()のテスト
   * UserでPostを検索することができる
   */
  public function testScopeByUser()
  {
    $users = User::factory()->count(2)->create();
    $posts = Post::factory()->for($users[0])->count(5)->create();
    $otherPost = Post::factory()->for($users[1])->create();

    $results = Post::byUser($users[0])->get();
    $this->assertEquals($results->count(), $posts->count());
    $this->assertNotContains($otherPost->id, $results->pluck('id')->toArray());
  }

scopeByUser()の結果と用意したテストデータのpostの数が一致してることをテストしたいので一見良さそうだが、下記の2点でテストとしてはちょっと微妙。

  • もしテストデータを変えてしまったときでも$posts->count()で都合よく計算されてしまう可能性がある
  • (Laravelのメソッドなので大丈夫だとは思うが)$posts->count()が正しいかもテストしなくてはいけなくなる
$this->assertEquals($results->count(), $posts->count());

After

  /**
   * scopeByUser()のテスト
   * UserでPostを検索することができる
   * 4人中3人のユーザーの投稿を検索した場合には、3人のユーザーの投稿のみが取得できる
   */
  public function testScopeByUserIds()
  {
    $users = User::factory()->count(2)->create();
    $posts = Post::factory()->for($users[0])->count(5)->create();
    $otherPost = Post::factory()->for($users[1])->create();

    $results = Post::byUserIds($userIds)->get();
    $this->assertEquals($results->count(), 5);
    $this->assertNotContains($otherPost->id, $results->pluck('id')->toArray());
  }

変更点

  • コメントで前提条件と結果を書く
  • 投稿数を実際の数字で明記
$this->assertEquals($results->count(), 5);

テストとしてより正確で、仕様書としてもわかりやすくなった!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0