phpunit必须是可遍历的或实现接口Iterator

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了phpunit必须是可遍历的或实现接口Iterator相关的知识,希望对你有一定的参考价值。

我正在尝试对我的服务进行单元测试,其中包含symfony2(http://symfony.com/doc/current/components/finder.html)的依赖项Finder组件。

我越来越 :

[例外] Mock_Finder_91776c5c :: getIterator()返回的对象必须是可遍历的或实现接口迭代器

服务 :

public function getFile($fileName, $path = '/')
    {

        if($this->wrapper == null || $this->connection == null)
            throw new LogicException("call method setFTP first");

        // get file on ftp server
        $this->connection->open();
        $downloadComplete = $this->wrapper->get($this->tmpDir . $fileName, $path . $fileName);
        $this->connection->close();

        if($downloadComplete == false)
            return false; // TODO exception ?

        // return file downloaded
        $this->finder->files()->in(__DIR__);
        foreach ($this->finder as $file) {
            return $file;
        }

        return false; // TODO exception ?

    }

而且测试

class FtpServiceTest extends phpUnit_Framework_TestCase
{

    protected $connectionMock;
    protected $ftpWrapperMock;
    protected $finderMock;

    protected function setUp()
    {
        $this->connectionMock = $this->getConnectionMock();
        $this->ftpWrapperMock = $this->getFTPWrapperMock();
        $this->finderMock = $this->getFinderMock();
    }

    protected function tearDown()
    {
    }

    private function getFinderMock()
    {
        return $this->getMockBuilder(Finder::class)
            ->disableOriginalConstructor()
            ->getMock('Iterator');
    }

    private function getConnectionMock()
    {
        return $this->getMockBuilder(Connection::class)
            ->disableOriginalConstructor()
            ->getMock();
    }

    private function getFTPWrapperMock()
    {
        return $this->getMockBuilder(FTPWrapper::class)
            ->disableOriginalConstructor()
            ->getMock();
    }

    // tests
    public function testMe()
    {

        // arrange
        $host = 'localhost';
        $user = 'user';
        $password = '1234';

        $filesArray = new ArrayObject(array(''));

        $service = new FtpService('var/tmp/');
        $service->setFTP($this->connectionMock, $this->ftpWrapperMock);
        $service->setFinder($this->finderMock);

        $this->connectionMock
            ->expects($this->once())
            ->method('open');

        $this->ftpWrapperMock
            ->expects($this->once())
            ->method('get')
            ->will($this->returnValue(true));

        $this->connectionMock
            ->expects($this->once())
            ->method('close');

        $this->finderMock
            ->expects($this->once())
            ->method('files')
            ->will($this->returnValue($this->finderMock));

        $this->finderMock
            ->expects($this->once())
            ->method('in')
            ->will($this->returnValue($filesArray));

        // act
        $file = $service->getFile('/file.zip');

        // assert
        $this->assertInstanceOf(SplFileInfo::class, $file);

    }

}
答案

Finder类的模拟实例需要实现/模拟方法getIteratorgetMock方法不接受参数,所以不要传递字符串'Iterator'-更改代码如下:

private function getFinderMock()
{
    return $this->getMockBuilder(Finder::class)
        ->disableOriginalConstructor()
        ->getMock();
}

并在测试方法中添加Mocked期望,例如:

    $this->finderMock->expects($this->once())
        ->method('getIterator')
        ->willReturn(new ArrayObject([$this->createMock(SplFileInfo::class)]));

希望这可以帮助。

以上是关于phpunit必须是可遍历的或实现接口Iterator的主要内容,如果未能解决你的问题,请参考以下文章

图解设计模式-Iterator模式

java 基础知识点必备

我可以用 PHPUnit 模拟接口实现吗?

ES6遍历器 生成器 学习整理

我可以使用PHPUnit模拟接口实现吗?

接口自动化测试PHPUnit-框架代码开发3