【问题标题】:PHPUnit - ReturnValueMap of Mocks not finding Mocked Class MethodsPHPUnit - 模拟的 ReturnValueMap 没有找到模拟类方法
【发布时间】:2017-08-04 07:42:28
【问题描述】:

我是单元测试新手,在 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 访问。

我错过了什么?问题(我天真地猜测)在于被模拟的成员的私有访问级别。

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

【问题讨论】:

    标签: php unit-testing mocking phpunit


    【解决方案1】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-10-07
      • 2013-01-27
      • 2016-06-13
      • 2021-04-27
      • 1970-01-01
      • 2016-04-21
      • 2011-10-28
      • 2021-06-16
      相关资源
      最近更新 更多