I want to test this simple query:
public function findArticlesByUsers($ids) {
$qb = $this->createQueryBuilder();
$qb
->addOr($qb->expr()->field('creator.id')->in($ids))
->addOr($qb->expr()->field('modifier.id')->in($ids))
->addOr($qb->expr()->field('publisher.id')->in($ids));
$query = $qb->getQuery();
$results = $query->execute();
return $results;
}
Where creator, modifier and publisher can be differents user.
I'm following this example of Symfony doc: http://symfony.com/doc/current/cookbook/testing/database.html#mocking-the-repository-in-a-unit-test
How to test this query builder?. My code look like this:
public function testFindArticlesByUsers()
{
$article = $this->getMock('\Acme\DemoBundle\Document\Article');
$article->expects($this->once())
->method('getCreator')
->will($this->returnValue($this->getMock('\Acme\DemoBundle\Document\\User')));
$article->expects($this->once())
->method('getModifier')
->will($this->returnValue($this->getMock('\Acme\DemoBundle\Document\\User')));
$article->expects($this->once())
->method('getPublisher')
->will($this->returnValue($this->getMock('\Acme\DemoBundle\Document\\User')));
$articleRepository = $this->getMockBuilder('\Doctrine\ODM\DocumentRepository')
->setMethods(array('findArticlesByUsers'))
->disableOriginalConstructor()
->getMock();
$articleRepository->expects($this->once())
->method('findArticlesByUsers')
->will($this->returnValue($article));
$documentManager = $this->getMockBuilder('\Doctrine\Common\Persistence\ObjectManager')
->disableOriginalConstructor()
->getMock();
$documentManager->expects($this->once())
->method('getRepository')
->will($this->returnValue($articleRepository));
$article2 = $documentManager->getRepository('BackendBundle:Article')
->findArticlesByUsers(1);
}
I haven't idea continuous with it and if this is the correct way. The error is:
Expectation failed for method name is equal to <string:getCreator> when invoked 1 time(s).
Method was expected to be called 1 times, actually called 0 times.
But I'm not sure how to test this and check the result.
Update:
I changed the code to pass the test(ok, it's green) but for me this test doesn't work fine because although delete findArticlesByUsers method the test is green. What I'm doing wrong?
public function testFindArticlesByUsers()
{
$userCreator = $this->getMock('\TT\BackendBundle\Document\User');
$userCreator->expects($this->any())
->method('getId')
->will($this->returnValue(1));
$userModifier = $this->getMock('\TT\BackendBundle\Document\User');
$userModifier->expects($this->any())
->method('getId')
->will($this->returnValue(2));
$userPublisher = $this->getMock('\TT\BackendBundle\Document\User');
$userPublisher->expects($this->any())
->method('getId')
->will($this->returnValue(3));
//Article mock
$article = $this->getMock('\TT\BackendBundle\Document\Article');
$article->expects($this->once())
->method('getCreator')
->will($this->returnValue($userCreator));
$article->expects($this->once())
->method('getModifier')
->will($this->returnValue($userModifier));
$article->expects($this->once())
->method('getPublisher')
->will($this->returnValue($userPublisher));
$articleRepository = $this->getMockBuilder('\Doctrine\ODM\DocumentRepository')
->setMethods(array('findArticlesByUsers'))
->disableOriginalConstructor()
->getMock();
$articleRepository->expects($this->once())
->method('findArticlesByUsers')
->will($this->returnValue($article));
$documentManager = $this->getMockBuilder('\Doctrine\Common\Persistence\ObjectManager')
->disableOriginalConstructor()
->getMock();
$documentManager->expects($this->once())
->method('getRepository')
->will($this->returnValue($articleRepository));
$article = $documentManager->getRepository('BackendBundle:Article')
->findArticlesByUsers(1);
$this->assertEquals(1, $article->getCreator()->getId());
$this->assertEquals(2, $article->getModifier()->getId());
$this->assertEquals(3, $article->getPublisher()->getId());
}
Update2:
I think finally I understand mock object :) so doing as above I'm mocking the repository but this isn't the objetive. My last code to test this method is:
public function testFindArticlesByUsers()
{
$userId = $this->dm->createQueryBuilder('AcmeBundle:User')
->field('username')->equals('fakeUser')
->getQuery()->getSingleResult()->getId();
$articles = $this->dm->getRepository('AcmeBundle:Article')
->findArticlesByUsers(array($userId));
$this->assertGreaterThanOrEqual(1, count($articles));
}
The test works although it depends on of it the user exists and has articles. Is ok the test?