douzhangcuo2174 2017-01-29 19:47
浏览 73

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

I mean something that acts like unittest.mock.patch in Python.

Is it possible in PHP?

-- UPDATE1 --

I'm using PHPUnit and try to mock the dependencies of SUT that is LoginController.

One of dependencies is the Fatfree Base. It's used directly in LoginController's constructor as Base::instance().

So, what I need is it to substitute the original Base class globally with the my mock class object. To make SUT use mocked Base::instance(). The only way I found is to provide this mock object on constructor of LoginController. To make this I was obligated to change the orignial SUT code that doesn't consider unit test requirements.

But I don't like this, due to there are many places in SUT code where different dependencies are used. So I need to mock those in PHP "class registry" globally to force "client" code use my class definitions to create objects.

In couple of words I need to mock class definition on system-wide level.

I'm looking for several hours on the net and still can't find the solution.

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 --

Optional $f3 constructor parameter is added by me. Originally it was just $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条回答 默认 最新

    报告相同问题?

    悬赏问题

    • ¥15 关于smbclient 库的使用
    • ¥15 微信小程序协议怎么写
    • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
    • ¥20 怎么用dlib库的算法识别小麦病虫害
    • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
    • ¥15 java写代码遇到问题,求帮助
    • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
    • ¥15 有了解d3和topogram.js库的吗?有偿请教
    • ¥100 任意维数的K均值聚类
    • ¥15 stamps做sbas-insar,时序沉降图怎么画