测试使用mockery在抽象类的构造函数中调用的公共函数时的未定义函数

时间:2013-09-12 18:01:29

标签: php phpunit mockery

我有一个抽象类,它在构造函数中调用公共函数。要测试这些调用是否正确执行,我必须模拟抽象类。每当我这样做时,我都无法在构造函数中进行公共函数调用。我收到以下错误:BadMethodCallException: Method ::setData() does not exist on this mock object。以下代码可能更好地解释了我的问题。

<?php

namespace Example\Tests;

use Mockery as m;
use PHPUnit_Framework_TestCase;

abstract class Foo
{

    private $data;

    public function __construct(array $defaults)
    {
        foreach ($defaults as $key => $value) {
            $this->setData($key, $value);
        }
    }

    public function getData()
    {
        return $this->data;
    }

    public function setData($key, $value)
    {
        return $this->data[$key] = $value;
    }
}


class ExampleTest extends PHPUnit_Framework_TestCase
{

    public function testDefaultsAreAssignedToData()
    {
        $expected = ['foo' => 'bar'];

        $foo = m::mock('\Example\Tests\Foo', [$expected]);

        $this->assertEquals($expected, $foo->getData());
    }
}

1 个答案:

答案 0 :(得分:1)

通常,您使用模拟作为被测试类的外部依赖项的替代。在这种情况下,您只想测试类的实际行为,而不是处理类Foo的任何依赖项。在这种情况下,实际上没有必要进行模拟,我只是为了测试目的而定义抽象类的具体实例。 也就是说,你可以重构这样的事情。

class ConcreteFoo extends Foo
{
}

class ExampleTest extends PHPUnit_Framework_TestCase
{
    public function testDefaultsAreAssignedToData()
    {
        $expected = ['foo' => 'bar'];

        $foo = new ConcreteFoo($expected);

        $this->assertEquals($expected, $foo->getData());
    }
}