PHPUnit - 需要多次包含的过程代码

PHPUnit - Procedural code needing to be included multiple times

我目前正在尝试构建一个 php 单元测试套件来测试一些按程序编写的 ajax 代码。 我无法编辑原始代码、fooBar.php,因为这可能会导致其他地方出现问题。当我尝试使用不同参数多次 运行 一个 php 文件时会出现此问题;该代码具有抛出重新声明异常的功能。下面是我正在处理的示例。

fooBar.php - php 文件通过 ajax 调用命中

$foo = $_POST['bar'];

function randomFunctionName(){
    echo "randomFunctionName";
}

if($foo == "fooBar"){
     $jsonResponse = array('success'=>true);
}else{
     $jsonResponse = array('success'=>false);
}

echo json_encode($jsonResponse);

fooBarTest.php - php单元测试文件

class fooBarTest extends \PHPUnit\Framework\TestCase
{   

   private function _execute() {
       ob_start();
       require 'fooBar.php';
       return ob_get_clean();
   }    

   public function testFooBarSuccess(){
       $_POST['bar'] = "fooBar";

       $response = $this->_execute();
       $this->assertTrue((strpos($response, 'success') !== false) && (strpos($response, 'true') !== false));

   }        
   public function testFooBarFailure(){
       $_POST['bar'] = "notFooBar";

       $response = $this->_execute();
       $this->assertTrue((strpos($response, 'success') !== false) && (strpos($response, 'false') !== false));

   }

所以当我运行这个测试时,我得到以下错误

PHP Fatal error:  Cannot redeclare randomFunctionName() (previously declared in.......

问题是因为 fooBar.php 在技术上已经存在,而第二个测试 testFooBarFailure() 是 运行。正如您所见,我需要重新运行 fooBar.php 以获得新的响应。

有什么方法可以从 php stack/memory 中删除 fooBar.php 这样我就可以再次 运行 它就像它从未从第一次测试中加载过?我已经尝试将第二个测试函数拉入它自己的测试 class 但是当我 运行 整个测试套件时,我得到了同样的错误。

PHP 有一个内置函数来检查是否定义了特定的函数,它被称为 function_exists。示例:

if (false === function_exists('randomFunctionName')) {
    function randomFunctionName()
    {
        echo "randomFunctionName";
    }
}

多亏了这个,你可以 include/require 文件多次,但函数只会加载一次。

第二种方法是使用 require_once 而不是 require (Difference between require, include and require_once?).

导入你的 fooBar.php 一次

所以我找到了一种方法来完成我正在寻找的事情。长话短说,我使用 CURL 来访问 ajax 文件。这允许我在我的测试中多次点击文件而不会导致任何重新声明问题。下面是我针对 fooBarTest.php 文件的解决方案示例。

class fooBarTest extends \PHPUnit\Framework\TestCase
{   

   public function testFooBarSuccess(){
       $postData = array('bar'=>"fooBar");

       $ch = curl_init();
       curl_setopt($ch, CURLOPT_URL, $url);
       curl_setopt($ch, CURLOPT_POST, true);
       curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
       curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); 

       $response = curl_exec($ch);      
       curl_close($ch);

       $this->assertTrue((strpos($response, 'success') !== false) && (strpos($response, 'true') !== false));

   }        
   public function testFooBarFailure(){
       $postData = array('bar'=>"notFooBar");

       $ch = curl_init();
       curl_setopt($ch, CURLOPT_URL, $url);
       curl_setopt($ch, CURLOPT_POST, true);
       curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
       curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); 

       $response = curl_exec($ch);      
       curl_close($ch);

       $this->assertTrue((strpos($response, 'success') !== false) && (strpos($response, 'false') !== false));

    }
}