Reputation: 95
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
Reputation: 16060
You should have will($this->returnValueMap...
instead of willReturn($this->returnValueMap...
Upvotes: 2