Symfony4でデータベースのテストをしたら、ServiceEntityRepositoryを継承したReposotiroyのテストがうまく行きませんでした。
最初書いたテストコードはこんな感じです。
1
2
3
4
5
6
7
8
|
// src/Repository/UserRepository.php
class UserRepository extends ServiceEntityRepository
{
public function averageScore() :float
{
...
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
// tests/UserRepositoryTest.php
class UserRepositoryTest extends KernelTestCase
{
/**
* @var UserRepository
*/
private $repository;
protected function setUp(): void
{
$kernel = self::bootKernel();
$em = $kernel->getContainer()->get('doctrine');
$repository = $em->getRepository(User::class);
}
public function testAverage(): void
{
$actual = $this->repository->averageScore();
static::assertSame(4.5, $actual);
}
}
|
このテストコードだと$this->repositoryに入っているオブジェクトがEntityRepositoryになってしまい、aveerageScore()メソッドが無いよとエラーになってしまいます。
解決策
DIからUserRepositoryのオブジェクトを取得する方法を使うのが今は良いかと思います。(てかそれしかなさそう)
1
2
3
4
5
6
|
// tests/UserRepositoryTest.php
protected function setUp(): void
{
$kernel = self::bootKernel();
$repository = $kernel->getContainer()->get(UserRepository::class);
}
|
しかし、これだとpublic = falseとなった状態なのでUserRepository::classのオブジェクトが取得できなくてエラーになります。
この問題は service_test.yamlを作成してpublic = trueに設定を解決しました。
1
2
3
4
5
6
7
8
9
10
|
# config/services_test.yaml
services:
_defaults:
autowire: true
autoconfigure: true
App\:
resource: '../src/*'
exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
public: true
|
これでテストのときはpublic = trueになるのでDIからオブジェクトが取得できます。
最後に
他にももっと良い方法があると思いますが、僕はわからなかったので知っている方がいたらコメントください!