2012-03-12 49 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

在哪里,什么时候是$ DB的全局设置在您的测试? – jpic 2012-03-12 15:11:04

+0

$ db不在测试本身内部,它必须被测试的文件内部。 – Josef 2012-03-12 15:20:49

+0

**和**何时初始化? :)无论如何,你是否尝试我的答案? – jpic 2012-03-12 17:12:24

回答

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.

很有可能,$ DB在检测过程中创建全局变量。因此,在测试之后它会被清除回去。你可以在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使测试失败wheras @backupGlobals disabled让它通过?

如果你想备份/除了$ DB的全局变量的恢复,定义这样一个类属性:

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.

相关问题