🦍
[Laravel]assertDatabaseHasの第一引数にはテーブル名ではなく、Modelを渡そう!
結論
- Before
$this->assertDatabaseHas('users', ['id' => 1]);
- After
$this->assertDatabaseHas(User::class, ['id' => 1]);
他にも、様々な形でテーブルを指定することが可能です。下記の書き方は全て同じ挙動をします。
$this->assertDatabaseHas('users',*);
$this->assertDatabaseHas(new User(),*)
$this->assertDatabaseHas((new User())->getTable(),*)
$this->assertDatabaseHas(User::getModel()->getTable(),*)
内部実装の解説
assertDatabaseHasの第一引数の$tableは、EloquentModelもしくはstringを受け取ります。
/**
* Assert that a given where condition exists in the database.
*
* @param \Illuminate\Database\Eloquent\Model|string $table
* @param array $data
* @param string|null $connection
* @return $this
*/
protected function assertDatabaseHas($table, array $data, $connection = null)
{
$this->assertThat(
$this->getTable($table), new HasInDatabase($this->getConnection($connection), $data)
);
return $this;
}
getTableメソッドでは、EloquentModelクラスならインスタンスを作成し、getTable()でテーブル名を取得しています。
/**
* Get the table name from the given model or string.
*
* @param \Illuminate\Database\Eloquent\Model|string $table
* @return string
*/
protected function getTable($table)
{
return is_subclass_of($table, Model::class) ? (new $table)->getTable() : $table;
}
まとめ
テーブル名を直接指定するのではなく、モデル経由で指定することでIDEの補完を受けやすくなります。加えて、テーブル名を変更した際に、テストコードへ影響しなくなるのもメリットだと思いました。
assertDatabase*系のメソッドにおいて、テーブル名は全て上記の方法で指定可能です。
公式には書かれていないが、便利なメソッドや引数の渡し方が存在する場合が多いので、定期的に書こうと思います。
オンライン家庭教師マナリンクを運営するスタートアップNoSchoolのテックブログです。 manalink.jp/ 創業以来年次200%前後で売上成長しつつ、技術面・組織面での課題に日々向き合っています。 カジュアル面談はこちら! forms.gle/fGAk3vDqKv4Dg2MN7
Discussion