falconsmilie
falconsmilie

Reputation: 95

PHPUnit - ReturnValueMap of Mocks not finding Mocked Class Methods

I'm new to unit testing and have come across something I don't understand when using returnValueMap() in PHPUnit. I've been googling for days now ...

Consider this code under test;

public function __construct(EntityManager $entityManager, AuditLog $auditLog) {
    $this->entityManager = $entityManager;
    $this->auditLog = $auditLog;
}

public function updateSomeId($oldId, $newId)
{
    $repositories = ['repo1', 'repo2', 'repo3'];

    foreach ($repositories as $repository) {
        try {
            $this->entityManager->getRepository($repository)
                ->updateSomeId($oldId, $newId);

        } catch (RepositoryException $e) {
            throw new SomeOtherException($e->getMessage(), $e->getCode(), $e);
        }
    }
}

The unit test code;

... code removed for brevity

    $repoMaintenance = new RepoMaintenance(
        $this->getEntityManagerMock(),
        $this->getAuditLogMock()
    );

    $this->assertTrue($repoMaintenance->updateSomeId(
        $this->oldId,
        $this->newId
    ));

/**
 * @return EntityManager
 */
private function getEntityManagerMock()
{
    $entityManagerMock = $this->getMockBuilder(EntityManager::class)
        ->disableOriginalConstructor()
        ->getMock();

    $entityManagerMock
        ->method('getRepository')
        ->willReturn($this->returnValueMap($this->getEntityManagerReturnValueMap()));

    return $entityManagerMock;
}

/**
 * @return array
 */
private function getEntityManagerReturnValueMap()
{
    return [
        ['repo1', $this->getRepo1Mock()],
        ['repo2', $this->getRepo2Mock()],
        ['repo3', $this->getRepo3Mock()],
    ];
}

/**
 * @return Repo1
 */
private function getRepo1Mock()
{
    return $this->getMockBuilder(Repo1::class)
        ->disableOriginalConstructor()
        ->getMock();
}

... Code removed for brevity

When the unit test is run, the following fatal error is returned;

PHP Fatal error: Call to undefined method PHPUnit_Framework_MockObject_Stub_ReturnValueMap::updateSomeId()

I've previously used mocks in return value maps with no issue accessing methods in a public context. The difference is I'm attempting to mock __construct() variables, which are set to private access within the SUT.

What am I missing? The problem (I would naively guess) is with the private access level of the members being mocked.

Is there a way to unit test this code? I don't want to hit the database at any point and this is the reason for mocking the calls to it.

Upvotes: 1

Views: 372

Answers (1)

akond
akond

Reputation: 16060

You should have will($this->returnValueMap... instead of willReturn($this->returnValueMap...

Upvotes: 2

Related Questions