【问题标题】:PHPUnit - Procedural code needing to be included multiple timesPHPUnit - 需要多次包含的程序代码
【发布时间】:2017-09-14 19:33:22
【问题描述】:

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

fooBar.php - 使用 ajax 调用命中的 php 文件

$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 - phpunit 测试文件

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

问题在于,在运行第二个测试 testFooBarFailure() 时,fooBar.php 在技术上已经存在。正如你所看到的,我需要重新运行 fooBar.php 以获得新的响应。

有没有办法从 php 堆栈/内存中删除 fooBar.php 以便我可以再次运行它,就好像它从未从第一次测试中加载一样?我尝试将第二个测试函数拉入它自己的测试类,但是当我作为一个整体运行测试套件时,我得到了完全相同的错误。

【问题讨论】:

    标签: php phpunit procedural


    【解决方案1】:

    所以我想出了一种方法来做我正在寻找的事情。长话短说,我使用 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));
    
        }
    }
    

    【讨论】:

      【解决方案2】:

      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 一次。

      【讨论】:

      • 您的任何建议都不起作用。检查函数是否存在正在改变原始的 fooBar.php。正如我所说,我无法更改原始代码。在 PHPUnit 测试文件中,我必须重新加载文件才能向其发送新信息。要求或包含一次不允许我这样做。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-03
      • 1970-01-01
      • 2013-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多