I try to Mock a request to my database following these 2 guides and one SO question:
So I have this code:
public static function kernelAndService(): array
{
$kernel = self::bootKernel(['environment' => 'test']);
$mangaService = static::getContainer()->get(MangaService::class);
$categoryRepository = static::getContainer()->get(CategoryRepository::class);
return [
[$kernel, $mangaService, $categoryRepository]
];
}
/**
* Test utilisant un mockage de données
* @dataProvider kernelAndService
*/
public function testGetBestOfTwoMangasByCategoryMock(
KernelInterface $kernel,
MangaService $mangaService,
CategoryRepository $categoryRepository
): void
{
// Boot du kernel pour accéder au container et déinir nos classes mockées
$kernel->boot();
$container = $kernel->getContainer();
// Mockage de notre classe MangaRepository
$mangaRepository = $this->createMock(MangaRepository::class);
$mangaRepository->expects(self::any())->method('getBestOfThreeMangasByCategory')
->withAnyParameters()
->willReturn([
new Manga(),
new Manga(),
])
;
// Mockage de l'entity manager pour lui passer notre repository
$entityManager = $this->createMock(ManagerRegistry::class);
$entityManager->expects(self::any())->method('getManager')->willReturn($entityManager);
$entityManager->expects(self::any())->method('getRepository')
->withAnyParameters()
->willReturn($mangaRepository);
$container->set(EntityRepository::class, $entityManager);
$container->set(MangaRepository::class, $mangaRepository);
$category = $categoryRepository->findOneBy(['name' => 'Ninja']);
$mangas = $mangaService->getBestOfThreeMangasByCategory($category);
assertCount(2, $mangas);
}
Upon the assertion, I have this error message: Failed asserting that actual size 1 matches expected size 2.
In my mock, I created 2 mangas entity while I have one in database and after dumping the $mangas
variable, I check that it contains the database result instead of the mocking expected result.
How can I mock my repository correctly ?
Symfony version, is 6.4.
I found the solution by getting my service again after setting the repository in the container. My service was initialized in the dataProvider with the non mocked MangaRepository
in the constructor.
// Mocking
$mangaRepository = $this->createMock(MangaRepository::class);
$mangaRepository->expects(self::any())->method('getBestOfThreeMangasByCategory')
->withAnyParameters()
->willReturn([
new Manga(),
new Manga(),
]);
// Add mock repository to container
$container->set(MangaRepository::class, $mangaRepository);
// Get a new service class initialized with mocked repository
$mangaService = $container->get(MangaService::class);
Then my reqest respond with my mocked result instead of the database result.