Prehistory

On some "non-very good" hosting, they like to have no alternative to disable certain functions via php.ini . In particular, sometimes useful parse_ini_file . In his project (the lightweight skeleton api) went around this way:

 if (function_exists('parse_ini_file')) { self::$settings = parse_ini_file(PROPERTIES); return; } $content = preg_grep("/^[\w .]+=.*/", explode(PHP_EOL, file_get_contents(PROPERTIES))); foreach ($content as $row) { $row = strstr($row . ';', ';', true); $key = trim(strstr($row, '=', true), " \n\r"); $value = trim(strstr($row, '=', false), " \"=\n\r"); self::$settings[ $key ] = $value; } 

Question

How do I now tie PHPUnit to test a piece of code with a handwritten parser?

It would be ideal to run it at runtime, but I couldn’t find any info.

PS Actually, I am at the very beginning of learning PHPUnit and maybe there is a true way that I just don’t know.

  • @rjhby I did not immediately understand the essence of the question, did not have time to delete the comment. - ilyaplot
  • Will you test on your server? If yes, then you can try php.net/manual/en/function.override-function.php or rename_function - ilyaplot
  • @ilyaplot APD redefines, not deletes. For local, runkit can be used. I wanted Travis to github to fasten and test there already. And if suddenly someone will use it, then the dependence on PECL completely unnecessary - rjhdby
  • Solving this question in any case will add conditions. This is either a PECL or a configuration. Through ini_set, it does not exactly work to disable functions, even through htaccess this is not done. - ilyaplot
  • one
    Write a test that will compare the result of the execution of the native function and the self-written one. And then it will not matter what methods INI is read. - ilyaplot

1 answer 1

Came from the back door.

Delivers a self-written parser in a separate private method

 private static function loadSettings() { self::$settings = function_exists('parse_ini_file') ? parse_ini_file(PROPERTIES) : self::loadSettingsHard(); } private static function loadSettingsHard() { $settings = []; $content = preg_grep("/^[\w .]+=.*/", explode("\n", file_get_contents(PROPERTIES))); foreach ($content as $row) { $row = strstr($row . ';', ';', true); $key = trim(strstr($row, '=', true), " \n\r"); $settings[ $key ] = trim(strstr($row, '=', false), " \"=\n\r"); } return $settings; } 

In the test method applied a dirty hack with Reflection

 public function testGetConfigValueHard() { $method = new ReflectionMethod( Config::class, 'loadSettingsHard' ); $method->setAccessible(true); $method->invoke(Config::class); $this->assertEquals( 'localhost', Config::get('db_host') ); } 

In general, this task allowed me to look at testing from an unexpected side. To cover the tests of this functionality, I was forced to reduce the cyclomatic complexity of my code (in fact, I applied the principle of sole responsibility), which is one of the pillars of a good application architecture.

As for the answer to a question, you can delete a function in runtime using the runkit_function_remove function, which is included in the PECL runkit extension. For many reasons, this approach is undesirable.