Dabagab
Dabagab

Reputation: 2875

PHPunit method mocking does not work

I do not understand why not work my method mocking, because the method run really, and do not want to return with the mocked value. (Symfony)

    $this->mockedObject = $this
        ->getMockBuilder('Object')
        //->setConstructorArgs(array('em' => $this->entityManager, 'router' => $this->mockedRouter))
        ->disableOriginalConstructor()
        ->setMethods(array('method1', 'method2'))
        ->getMock();

    $this->mockedObject
        ->expects($this->once())
        ->method('method2')
        ->willReturn(9);

So as you see I mocked the method2, but method2 never returns with 9 value, because it is run:

Error: Call to a member function createQueryBuilder() on null

Here the original method2:

   private function method2($repository) {
        $qb = $this->em->createQueryBuilder();
        $qb->select('count(e.id)');
        $qb->from($repository, 'e');
        return $qb->getQuery()->getSingleScalarResult();
    }

And here the problem, because the mockedObject calls the method2() with the createQueryBuilder method

How can I achieve that the method2 be mocked and returns with 9 value?

Upvotes: 0

Views: 2156

Answers (1)

Aleksander Wons
Aleksander Wons

Reputation: 3967

This happens because you cannot mock private methods like this. To answer your question you can still do it by changing visibility of the method:

$method = new ReflectionMethod('Object', 'method2');
$method->setAccessible(true);

Though I wouldn't recommend testing private methods. You should try to mock dependencies of this class to return what you need. Mocking private methods usually means there is something wrong with a logic of a class.

I also wouldn't recommend changing visibility of the method in the original class since you should never change your code just to make tests happy. If a method would be otherwise private there is no single reason to change it to protected or public.

Upvotes: 4

Related Questions