2
votes

I am new to TDD. I am stuck on some unit testing... please take a look at my code... and thanks in advance...

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

Want to test:

class ParserTest{

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

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

    }

}

My Question/Request:

Can you please fill these test. I am stuck on this like forever...and unable to continue my TDD journey.

Some Steps (you can skip these lines):

I have tried my best to solve this my own, but unable to do so. Some steps are..

I tried phpunit's native mockery, padraic/mockery (git), codeception/aspect-mock (git) to mock _checkCurlExistence() method for two situation... I am not sure if I done it right...thats why, not posting those code...

I tried Reflection Api, Class extending with method overriding via magic method __call()... to dynamically convert protected method to public method to help mocking...

I also done a lot of googling. Know about that best practice is to only test public method. But my public method depend on protected method...so how can I test???

1
i would prefer to test it through checkCurlExtension() , i mean it throws an Exception if the extension is not found. use it in your test case. F.e $this->setExpectedException("CurlException"); and you are done. and that would be after you remove the "exit()" function. just use the exception to your advantagesatin
If you want to test a protected/private method, you could extend the class with a special test class that exposes those methods publicly?halfer
The protected/private methods should not be tested.tereško

1 Answers

0
votes

Found a way to mock php built-in functions via PHPUnit function mocker extension

So I can easily test the 2 scenarios now.

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

    }
}