Welcome to Abdul Malik Ikhsan's Blog

Testing Doctrine 2 Query Result from QueryBuilder with PHPUnit

Posted in testing, Tutorial PHP by samsonasik on March 18, 2015

DoctrineYes, to get the result of QueryBuilder, we need to get Query first(which is final class :p). So, how to mock it? Impossible, huh? Don’t worry, we have the Query Abstract class! I got the very smart solution from this post by Julius Beckmann. Let me create a use case and paraphrase for that sample. The way we an do is we can mock the Abstract class and registers methods that we want to use, for example, on this case, the getResult method.

Use Case

We need to get latest data of news with limit and order, so we use QueryBuilder and its Query Result like the following :

namespace OurApp\Service;

use OurApp\Entity\News;
use Doctrine\ORM\EntityManager;

class NewsService
     * @var EntityManager
    private $manager;
     * Construct
     * @param EntityManager $manager
    public function __construct(EntityManager $manager)
        $this->manager = $manager;    
     * Get Last Recent News
     * @param int $limit
     * @return array
    public function getLastRecentNews($limit)
        $result = $this->manager->getRepository(News::class)->createQueryBuilder('n')
                       ->orderBy('n.id', 'DESC')
        return $result;

Of course, you can create instance of above class by factory with constructor injection.

The Test

This is it, we can mock the EntityManager, expects EntityRepository, expects QueryBuilder, use QueryBuilder until getResult() ready to be called, and use AbstractQuery with define only ‘getResult’ for expecting Result.

namespace OurAppTest\Service;

use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
use Doctrine\ORM\AbstractQuery;
use OurApp\Entity\News;
use OurApp\Service\NewsService;
use PHPUnit_Framework_TestCase;

class NewsServiceTest extends PHPUnit_Framework_TestCase
     * @var EntityManager
    private $manager;
     * @var NewsService
    private $service; 
    public function setUp()
        $this->manager  = $this->getMockBuilder(EntityManager::class)

        $this->service = new NewsService($this->entityManager);
    public function testLastRecentNews()
        $repository = $this->getMockBuilder(EntityRepository::class)
        $queryBuilder = $this->getMockBuilder(QueryBuilder::class)
        // We use QueryBuilder as Fluent Interface
        // several times, so we need to make it sequence
                     ->with('n.id', 'DESC')

        // We use AbstractQuery
        $getQuery = $this->getMockBuilder(AbstractQuery::class)
        $entity1 = new News();
        $entity1->setHeadLine('Hello world from PHP');
        $entity2 = new News();
        $entity2->setHeadLine('Hello world from PHPUnit');
        $result = [
            0 => $entity1,
            1 => $entity2,
        $this->assertEquals($result, $this->service->getLastRecentNews(2));

I hope this sample make easier to understand for you who find a way to solve it.

Ocramius suggest to not do it. He suggest to use Fixture instead like his gist. I created a new post in favor of it.

References :
1. http://h4cc.tumblr.com/post/61502458780/phpunit-mock-for-doctrine-orm-query
2. https://gist.github.com/gnutix/7746893

Image :

8 Responses

Subscribe to comments with RSS.

  1. […] is an immediate post to incorporate my latest post about Mocking DoctrineORMAbstractQuery to test querybuilder. Well, while that works, Ocramius – A Doctrine core team – said that we shouldn’t […]

    • Test Unit said, on February 9, 2017 at 11:20 pm

      It is necessary to remark at the beginning 🙂

  2. Bartosz Zając said, on January 4, 2017 at 6:09 pm

    This is very very usefull post

  3. johannes said, on March 23, 2018 at 7:06 pm

    Is $$this->service in NewsServiceTest::setUp correct? Doesn’t make sense to me

  4. tim said, on September 27, 2018 at 5:37 pm

    thank you very much. was quite helpful

  5. Kashif said, on June 4, 2019 at 3:51 am

    Your blog has helped me much, at very critical time. I really thankful to you, as well many prayers to you.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: