I try to create a test for a custom controller. In this one, this is what is executed:
Code
$users = $this->getDoctrine()
->getRepository('MyBundle:User')
->findAllOrderedByName();
In the test controller, this is what I am doing:
$entityManager = $this
->getMockBuilder('Doctrine\ORM\EntityManager')
->setMethods(['getRepository', 'clear'])
->disableOriginalConstructor()
->getMock();
$entityManager
->expects($this->once())
->method('getRepository')
->with('MyBundle:User')
->will($this->returnValue($userRepositoryMock));
// Set the client
$client = static::createClient();
$client->getContainer()->set('doctrine.orm.default_entity_manager', $entityManager);
Problem
But at the end the test fails because my mock seems to no be used:
tests\MyBundle\Controller\ListingControllerTest::testAllAction Expectation failed for method name is equal to string:getRepository when invoked 1 time(s). Method was expected to be called 1 times, actually called 0 times.
Any idea ?
EDIT
Following remarks on comments, I created a service:
services:
my.user.repository:
class: MyBundle\Entity\UserRepository
factory: ['@doctrine.orm.default_entity_manager', getRepository]
arguments:
- MyBundle\Entity\User
So now, I "just" have to mock the repo:
$userRepositoryMock = $this->getMockBuilder('MyBundle\Entity\UserRepository')
->disableOriginalConstructor()
->setMethods(['findAllOrderedByName'])
->getMock();
$userRepositoryMock
->expects($this->once())
->method('findAllOrderedByName')
->will($this->returnValue($arrayOfUsers));
and inject it into the container:
$client->getContainer()->set('my.user.repository', $userRepositoryMock);
But I still have the same issue
Don't inject container/entity manager in the testing class, instead inject doctrine repositories directly. Also, don't create kernel in your test, tests should run fast.
UPDATE 1:
The testing service should require repository in constructor. So in your test you are able to replace it with mock.
$client = static::createClient()
is for testing controllers against the real database with fixtures (functional test). Don't use it for testing services with mocked dependencies (unit test).
UPDATE 2: Example of unit test:
class UserServiceTest extends UnitTestCase
{
public function test_that_findAllWrapper_calls_findAllOrderedByName()
{
//GIVEN
$arrayOfUsers = [$user1, $user2];
$userRepo = $this->getMockBuilder('AppBundle\Repository\UserRepository')
->disableOriginalConstructor()
->getMock();
$userRepo
->expects($this->once())
->method('findAllOrderedByName')->willReturn($arrayOfUsers);
$userService = new UserService($userRepo);
//WHEN
$result = $userService->findAllWrapper();
//THEN
$this->assertEquals($arrayOfUsers, $result);
}
}
class UserService {
private $userRepo;
public function __construct(UserRepository $repo)
{
$this->userRepo = $repo;
}
public function findAllWrapper()
{
return $this->userRepo->findAllOrderedByName();
}
}