Php单元测试,带有模拟的受保护方法

时间:2013-10-03 11:41:01

标签: php oop unit-testing mocking tdd

我是TDD的新手。我被困在一些单元测试中......请看看我的代码......并提前感谢...

class Parser{

    protected function _checkCurlExistence()
    {
        // Unable to to mock function_exists, thats why fallback with this method

        return function_exists('curl_version');
    }


    public function checkCurlExtension()
    {

        // I want to test 2 situations from this method...
        // 1. if curl extension exists
        // 2. or when curl extension does not exists...throw error

        if($this->_checkCurlExistence() === false){

            try{
                throw new CurlException(); //Some curl error handler exception class
            }catch(CurlException $error){
                exit($error->getCurlExtensionError());
            }

        }

        return true;
    }
}

想要测试:

class ParserTest{

    /**
    * @expectedException CurlException
    */
    public function testCheckCurlExtensionDoesNotExists()
    {
        //Some testing code with mocking...
    }

    public function testCheckCurlExtensionExists()
    {
       //Some testing code with mocking..and assertion 

    }

}

我的问题/要求:

请填写这些测试。我永远坚持这个......并且无法继续我的TDD之旅。

一些步骤(您可以跳过这些行):

我尽力解决这个问题,但无法解决。一些步骤是......

我尝试了 phpunit的本机嘲弄 padraic / mockery (git), codeception / aspect-mock (git)来模拟_ checkCurlExistence()两种情况的方法......我不确定我是否做得对...这就是为什么,不发布那些代码......

我尝试了 Reflection Api ,通过魔术方法 __call()...进行方法覆盖的类扩展,将受保护的方法动态转换为公共方法以帮助模拟...

我也做了很多谷歌搜索。了解最佳实践只是测试公共方法。但我的公共方法依赖于受保护的方法......所以我该如何测试???

1 个答案:

答案 0 :(得分:0)

找到了一种通过模拟php内置函数的方法 PHPUnit function mocker extension

所以我现在可以轻松测试这两种情况。

namespace 'myNameSpace';

class Parser{

    public function checkCurlExtension()
    {
        // I want to test 2 situations from this method...
        // 1. if curl extension exists
        // 2. or when curl extension does not exists...throw error

        if(function_exists('curl_version') === false){
            throw new CurlException(); //Some curl error handler exception class
        }

        return true;
    }


}

class ParserTest{

    private $parser;

    /**
    * @expectedException CurlException
    */
    public function testCheckCurlExtensionDoesNotExists()
    {
        $funcMocker = \PHPUnit_Extension_FunctionMocker::start($this, 'myNameSpace')
        ->mockFunction('function_exists')
        ->getMock();

        $funcMocker->expects($this->any())
        ->method('function_exists')            
        ->will($this->returnValue(false));

        $this->parser->checkCurlExtension(); 

    }

    public function testCheckCurlExtensionExists()
    {
       //we can do same here...please remember DRY...

    }
}