In my code I have a file that initializes a MySQLi class.
File a
:
$db = new Database(); //MySQLi class
Anyways, there is a file that includes this database class. That file also includes other files that has function declared in it. I'm using global
to contact $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())
}
}
I get:
Fatal error: Call to a member function getArray() on a non-object
I investigated:
var_dump($db);
function xy(){
global $db;
var_dump($db);
...
}
The first dump gave me the MySQLi object,
the second dump gave me NULL
Something is wrong with the global variable in file_b.
Additional Information: I'm using PHPUnit and I'm running it in the command prompt. In a normal browser everything works fine.
The Solution is to hardcode the Database Class into the $GLOBALS
Array.
$GLOBALS['db'] = $db;
Adding this as a PHPUnit bootstrap worked fine for me. It is kind of hacky and should be used in Test cases.
You must fully understand PHPUnit's manual 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.
Very likely, the $db global variable is created during a test. Thus, it is erased back to null after the test. You could either set the global variable in setUp(), either manage yourself how you want PHPUnit to behave with this global. There are several ways to do that.
Switch the value of @backupGlobals and it won't do the backup/restore operation between tests:
<?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' );
}
}
Do you understand why @backupGlobals enabled
make the test fail wheras @backupGlobals disabled
make it pass ?
If you want backup/restore of the global variables except for $db, define such a class attribute:
protected $backupGlobalsBlacklist = array( 'db' );
This works too. Actually that would be even better since it's nice to have test isolation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With