模拟正在测试的类的公共方法

时间:2015-09-21 09:32:19

标签: unit-testing phpunit mockery

我试图对一个类进行单元测试,其中一个公共方法(方法1)使用同一个类中的另一个公共方法(方法2)。 E.g。

class MyClass {
    public function method1()
    {
        $var = $this->method2();
        // Do stuff with var to get $answer
        return $answer;
    }

    public function method2()
    {
        // Do complex workings out to get $var
        return $var;
    }
}

现在,method2已经过单元测试,我不想在测试method1时建立一个参数来实际调用它。我只想模拟method2并在我的测试中定义将返回的内容。这就是我所拥有的:

function test_method1()
{
    $myClass = new MyClass();

    $mockedMyClass = Mockery::mock('MyClass');
    $mockedMyClass->shouldReceive('method2')->once()->andReturn([1,2,3,4]); // mocked $var returned to be used in the rest of method1

    $answer = $myClass->method1();
    // Assertions
}

显然,这并不起作用,因为被测试的方法与包含被模拟的方法在同一个类中,因此无法将模拟类作为依赖项传递。什么是模拟方法2的最好方法?

1 个答案:

答案 0 :(得分:2)

您可以使用测试框架的Partial Mock功能,允许您测试被标记为模拟的同一个类。 例如,假设您修改了类:

<?php


namespace Acme\DemoBundle\Model;


class MyClass {
    public function method1()
    {
        $var = $this->method2();
        $answer = in_array(3, $var);
        // Do stuff with var to get $answer
        return $answer;
    }

    public function method2()
    {
        // Do complex workings out to get $var
        return array();
    }
}

测试如下:

<?php
namespace Acme\DemoBundle\Tests;


class MyClassTest  extends \PHPUnit_Framework_TestCase {

    function test_method1()
    {

        $mockedMyClass = \Mockery::mock('Acme\DemoBundle\Model\MyClass[method2]');
        $mockedMyClass->shouldReceive('method2')->once()->andReturn([1,2,3,4]); // mocked $var returned to be used in the rest of method1

        $answer = $mockedMyClass->method1();
        $this->assertTrue($answer);        // Assertions
    }

}

希望这个帮助