PHPUnit - Mocks的ReturnValueMap没有找到Mocked类方法

时间:2017-08-04 07:42:28

标签: php unit-testing mocking phpunit

我是单元测试的新手,在PHPUnit中使用returnValueMap()时遇到了一些我不明白的事情。我现在谷歌搜索了好几天......

考虑这个测试代码;

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);
        }
    }
}

单元测试代码;

... 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

运行单元测试时,会返回以下致命错误;

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

我以前在返回值映射中使用了模拟,在公共上下文中没有问题访问方法。不同之处在于我试图模拟__construct()变量,这些变量在SUT中设置为private访问。

我错过了什么?问题(我会天真地猜测)是被嘲笑成员的私人访问级别。

有没有办法对这段代码进行单元测试?我不想在任何时候点击数据库,这就是模拟调用它的原因。

1 个答案:

答案 0 :(得分:2)

您应该will($this->returnValueMap...而不是willReturn($this->returnValueMap...