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のデータ') {....
となるのだと理解すると、ちょっとわかりやすくなりました。