2012-03-12 2 views
3

В моем коде у меня есть файл, который инициализирует класс MySQLi.Глобальные переменные внутри значения функций NULL

File a:

$db = new Database(); //MySQLi class 

В любом случае, есть файл, который включает в себя этот класс базы данных. Этот файл также включает в себя другие файлы, в которых есть функция, объявленная в нем. Я использую global связаться $db

File b:

function xy(){ 
    global $db; 
    $sql = "..." 
    return $db->getArray($sql); 
} 

Testfile:

require "file_a.php"; 
require "file_b.php"; 
require_once "PHPUnit/Framework/TestCase.php"; 

class testProblemStatistics extends PHPUnit_Framework_TestCase { 

    testArray(){ 
     $this->assertTrue(array_key_exists('xy', $this->xy()) 
    } 
} 

я получаю:
Фатальная ошибка: Вызов функции-члена GetArray() на не объект

я исследовал:

var_dump($db); 
function xy(){ 
    global $db; 
    var_dump($db); 
    ... 
} 

Первый дамп дал мне MySQLi объект,
второй дамп дал мне NULL

Что-то не так с глобальной переменной в file_b.

Дополнительная информация: Я использую PHPUnit, и я запускаю его в командной строке. В обычном браузере все работает нормально.

+0

Где и когда это $ дб глобальные настройки в ваших тестах? – jpic

+0

$ db не находится внутри самого теста, его внутри файла, который должен быть протестирован. – Josef

+0

** и ** когда он инициализирован? :) В любом случае, вы попробовали мой ответ? – jpic

ответ

9

Решение заключается в жестком кодировании класса базы данных в массив $GLOBALS.

$GLOBALS['db'] = $db; 

Добавление это как PHPUnit бутстрапе работал нормально для меня. Это своего рода хакерство и должно использоваться в тестовых случаях.

4

Вы должны полностью понимать PHPUnit Руководство on Global State:

By default, PHPUnit runs your tests in a way where changes to global and super-global variables ($GLOBALS, $_ENV, $_POST, $_GET, $_COOKIE, $_SERVER, $_FILES, $_REQUEST) do not affect other tests. Optionally, this isolation can be extended to static attributes of classes.

Очень вероятно, что $ дб глобальная переменная создается во время теста. Таким образом, после теста он удаляется до нуля. Вы можете либо установить глобальную переменную в setUp(), либо самостоятельно управлять тем, как вы хотите, чтобы PHPUnit вел себя с этим глобальным. Существует несколько способов сделать это.

Переключите значение @backupGlobals и он не будет делать резервное копирование/восстановление операции между тестами:

<?php 

function xy() { 
    global $foo; 
    var_dump($foo); 
    return $foo; 
} 

/** 
* @backupGlobals disabled 
*/ 
class someTestCase extends PHPUnit_Framework_TestCase { 

    public function testA() { 
     global $foo; 
     $foo = 'bar'; 
    } 

    public function testB() { 
     global $foo; 
     $this->assertEquals($foo, 'bar'); 
    } 
} 

Вы понимаете, почему @backupGlobals enabled сделать тест не в состоянии @backupGlobals disabled Тогда как сделать это пройти?

Если вы хотите резервного копирования/восстановления глобальных переменных для $ дб, за исключением, определить такой атрибут класса:

protected $backupGlobalsBlacklist = array('db'); 

Это тоже работает. На самом деле это было бы еще лучше, так как было бы неплохо иметь тестовую изоляцию.

3

Похоже, что при запуске в PHPUnit код верхнего уровня в файле a выполняется внутри некоторого метода, а присвоение $ db относится к локальной переменной. Сделать это явно глобальный, так что он остается таким образом в тестовом прогоне:

global $db; 
$db = new Database(); //MySQLi class 
0

Ответ на zerkms помогает мне: https://stackoverflow.com/a/4074833/2016870:

I bet you're executing this code by including this file inside another function.

So you need to mark as global first variable occurency too.

Btw, global variables is weird, the more simple and correct way to pass the data to the function - is to use funtction parameters.

Смежные вопросы