2012-03-12 81 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.

相關問題