В настоящее время я пытаюсь создать набор тестов phpunit для тестирования некоторого кода ajax, который написан процедурно. Я не могу редактировать исходный код, fooBar.php, потому что это может вызвать проблемы в другом месте. Проблема возникает, когда я пытаюсь запустить php-файл несколько раз с разными параметрами; в коде есть функция, которая выдает redeclare исключения. Ниже приведен пример того, с чем я имею дело.
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 — тестовый файл 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.......
Проблема заключается в том, что fooBar.php технически уже существует, когда запускается второй тест testFooBarFailure (). Как вы можете видеть, мне нужно повторить fooBar.php для того, чтобы получить новый ответ.
Есть ли способ удалить fooBar.php из стека / памяти php, чтобы я мог запустить его снова, как если бы он никогда не загружался с первого теста? Я пытался вытащить вторую функцию тестирования в ее собственный класс тестирования, но когда я запускаю весь набор testsuite целиком, я получаю точно такую же ошибку.
Поэтому я нашел способ сделать то, что искал. Короче говоря, я использую 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));
}
}
PHP имеет встроенную функцию для проверки того, что определенная функция определена, она называется function_exists
. Пример:
if (false === function_exists('randomFunctionName')) {
function randomFunctionName()
{
echo "randomFunctionName";
}
}
Благодаря этому вы можете include
/require
файл много раз, но функция будет загружена один раз.
Второй способ — просто импортировать fooBar.php
один раз используя require_once
вместо require
(Разница между require, include и require_once?).