Mockery& PHPUnit:此模拟对象上不存在方法

时间:2016-05-20 14:12:48

标签: php unit-testing mocking phpunit mockery

你能告诉我问题出在哪里吗?我有一个文件 GeneratorTest.ph p,其中包含以下测试:

<?php

namespace stats\Test;

use stats\jway\File;
use stats\jway\Generator;

class GeneratorTest extends \PHPUnit_Framework_TestCase
{

    public function tearDown() {
        \Mockery::close();
    }

    public function testGeneratorFire()
    {
        $fileMock = \Mockery::mock('\stats\jway\File');
        $fileMock->shouldReceive('put')->with('foo.txt', 'foo bar')->once();
        $generator = new Generator($fileMock);
        $generator->fire();
    }

    public function testGeneratorDoesNotOverwriteFile()
    {
        $fileMock = \Mockery::mock('\stats\jway\File');
        $fileMock->shouldReceive('exists')
            ->once()
            ->andReturn(true);

        $fileMock->shouldReceive('put')->never();

        $generator = new Generator($fileMock);
        $generator->fire();
    }
}

以下是文件生成器类:

File.php:

class File
{
    public function put($path, $content)
    {
        return file_put_contents($path, $content);
    }

    public function exists($file_path)
    {
        if (file_exists($file_path)) {
            return true;
        }
        return false;
    }
}

Generator.php:

class Generator
{
    protected $file;

    public function __construct(File $file)
    {
        $this->file = $file;
    }

    protected function getContent()
    {
        // simplified for demo
        return 'foo bar';
    }

    public function fire()
    {
        $content = $this->getContent();
        $file_path = 'foo.txt';

        if (! $this->file->exists($file_path)) {
            $this->file->put($file_path, $content);
        }
    }

}

因此,当我运行这些测试时,我收到以下消息: BadMethodCallException:此模拟对象上不存在方法... :: exists()

enter image description here

1 个答案:

答案 0 :(得分:7)

错误消息对我来说似乎很清楚。您只对put方法设置了期望值,但没有为exists设置期望值。 exists方法由所有代码路径中的测试类调用。

public function testGeneratorFire()
{
    $fileMock = \Mockery::mock('\stats\jway\File');
    $fileMock->shouldReceive('put')->with('foo.txt', 'foo bar')->once();

    //Add the line below
    $fileMock->shouldReceive('exists')->once()->andReturn(false);

    $generator = new Generator($fileMock);
    $generator->fire();
}