dataProviderの書き方

PHPUnit

Laravelユニットテストの勉強で(多分)初めて触れたデータプロバイダについて

忘れないうちにメモ。

(書く側として)わかりやすい書き方

以下のように書かれていると、1つ1つに何を書いているのかわかりやすいですよね。

  public function dataproviderPostdata()
  {
      'titleがnullの場合' => [
        'title' => null,
        'content' => Str::random(1000),
        'expected' => false
      ],
      'titleが51文字の場合' => [
        'title' => Str::random(51),
        'content' => Str::random(1000),
        'expected' => false
      ],
  }

‘titleが51文字の場合’という日本語はただのキー名のようなもので、テストでエラーが出た時などにわかりやすくなる便利なもの。

その’titleが51文字の場合’というキー名を持つデータは、

     [
        'title' => Str::random(51),
        'content' => Str::random(1000),
        'expected' => false
      ]

という配列になっています。それぞれにtitle, content, expectedとなっていてわかりやすいですよね。

でも、これだとテストしたいデータが増えるとこの配列セットがどんどん増えてしまいますし、

テストしたいのはどの項目なのか、タイトルなのか?コンテントなのか?がわかりにくいです。

見通し・後々のためにデフォルト値を設定したメソッドを作る

それぞれのテストデータに対してtitle content を書き込むのは大変ですし、前述のようにテストしたい項目がぼけてしまいます。

そこで、テストデータとなる配列のデフォルト値を設定します。

private function params($overrides = [])
  {   
    return array_merge([ 
      'title' => Str::random(50),
      'content' => Str::random(1000),
    ], $overrides);
  }

このメソッドは配列を返しています。

引数で配列を受け取り、arrey_mergeでデフォルト値(第一引数)と第二引数をマージさせ、新しい配列をリターンするメソッドです。

※array_mergeは、キー名が被った場合第二引数を優先します

それでこれを、dataProviderの中で以下のように使います

  public function dataproviderPostdata()
  {
    return [
      'titleがnullの場合' => [ 
        $this->params(['title' => null]),
        false
      ],
 }

‘titleがnullの場合’はそのままで、配列の1つめに先ほど作ったparamsメソッドが使われています。

引数にはtitleというキー名とnullが渡されています。

つまり・・・

$this->params(['title' => null]),

これは、array_mergeされた配列、

[ 
      'title' => null,
      'content' => Str::random(1000),
]

が入ってきます!!すごい!

ちゃんとtitleとcontentがセットされた配列が入るのに、dataProviderメソッドの中ではテストしたい箇所(今回はtitle)のみを記述できるので何をテストしたいのかが明らかになります。

実際テストメソッドに使う場合

ではテストメソッドにdataProviderを読み込んでテストしてみましょう!

/**
   * 
   * @dataProvider dataproviderPostdata
   * @test
   */
  public function 掲示板に投稿処理($postparam, $expected) 
  {
    $user = factory(User::class)->create();

    $this->actingAs($user)
      ->get('/posts');

    $response = $this->post('/posts', $postparam);

    if ($expected === true) {
      $response->assertSessionHasNoErrors();
    } else {
      $response->assertSessionHasErrors();
    }
  }

第一引数

このテストメソッドの引数は2つあります。

第一引数の$postparamには、dataProviderで作った配列の0番目のデータが入ります。

つまりこれの

 'titleがnullの場合' => [ 
$this->params(['title' => null]),
false
],

0番目はこちらで

$this->params(['title' => null]),

つまりこれは

[ 
      'title' => null,
      'content' => Str::random(1000),
]

この配列が入っているということです。

第二引数

次に第二引数である$expected。こちらはわかりやすいですよね。

配列でもなんでもなく、これのキー名1のデータである

 'titleがnullの場合' => [ 
        $this->params(['title' => null]),
        false
      ],

false が入ります。

まとめ

dataProviderのデータとメソッドへ渡した際の引数での受け取り方が???だったのですが、

単純に

'titleがnullの場合' => [ 
        'キー名0のデータ',
        'キー名1のデータ'
      ],

というシンプルな配列のデータがテストメソッドに渡り、

public function 掲示板に投稿処理( 'キー名0のデータ', 'キー名1のデータ')  {....

となるのだと理解すると、ちょっとわかりやすくなりました。

タイトルとURLをコピーしました