如何在php中使用mock修补类定义?

时间:2017-01-29 19:47:09

标签: php class mocking patch

我的意思是像Python中的unittest.mock.patch一样。

是否可以在PHP中使用?

- UPDATE1 -

我正在使用PHPUnit并尝试模拟S LoginController的依赖关系。

其中一个依赖项是Fatfree Base。它在LoginController的构造函数中直接用作Base::instance()

所以,我需要的是用原始的Base类替换我的mock类对象。要使SUT使用模拟Base::instance()。我找到的唯一方法是在LoginController的构造函数上提供这个模拟对象。为此,我有义务更改不考虑单元测试要求的orignial SUT代码。

但我不喜欢这样,因为SUT代码中有很多地方使用不同的依赖项。所以我需要在PHP"类注册表"中嘲笑那些全球迫使客户"代码使用我的类定义来创建对象。

在几个单词中,我需要在系统级别上模拟类定义。

我在网上寻找了好几个小时但仍无法找到解决方案。

class LoginControllerTest extends TestCase
{
    public function setUp()
    {
        $MockF3Base = $this->createMock(Base::class);
        $MockF3Base->method('get')->will($this->returnCallback(
            function($p) {
                $mock_params = [
                    'LANGUAGES'=>['en', 'ru'],
                    'COOKIE.lg'=>'en',
                    'user'=>new GuestModel(),
                    'AJAX'=>true,
                    'BASE'=>BASE_URL
                ];

                if (array_key_exists($p, $mock_params))
                {
                    return $mock_params[$p];
                }

                return null;
            }));

        $sut = $this->getMockBuilder(LoginController::class)
            ->setConstructorArgs([$MockF3Base])
            ->setMethods(['json_success'])
            ->getMock();

        $this->_sut = $sut;
    }

    public function testMustLoginIf__()
    {
       $this->_sut->expects($this->once())->method('json_success')->with($this->stringContains(BASE_URL.'/kassa'));
       $this->_sut->LoginAction();
    }

    private $_sut;
}

- UPDATE2 -

我添加了可选的$f3构造函数参数。最初它只是$this->f3 = Base::instance();

class LoginController{

    public function __construct($f3 = null){
        $this->f3 = is_null($f3)? Base::instance(): $f3;
        $this->section = $this->f3->get('PARAMS.section') or $this->section = 'index';
        $this->name = substr(get_class($this), 0, -10);
        $user = new GuestModel();
        $session = $this->f3->get('COOKIE.PHPSESSID');
        if($session && $user->load(['`session`=?', $session])){

        }
        $this->f3->set('user', $user);

        $language = $this->f3->get('COOKIE.lg');
        $language = array_key_exists($language, $this->f3->get('LANGUAGES')) ? $language : 'en';
        $this->f3->set('LANGUAGE', $language);

        if(!$user->dry() && ($user->session('language') != $language)){
            $user->session('language', $language, true);
        }
    }
}

0 个答案:

没有答案