2011-09-02 40 views
3

我正在爲類加載器編寫一些單元測試,並且第一個測試是在那裏斷言試圖引用一個類而不先加載它確實會失敗。PHPUnit測試可能會出現致命錯誤嗎?

測試看起來是這樣的:

/** 
* @expectedException PHPUnit_Framework_Error 
*/ 
public function testInstantiateUnloadedClass() { 
    $foo = new Foo(); 
} 

可悲的是,在運行測試產生這樣的信息:

PHP Fatal error: Class 'Foo' not found in /Users/jfvaren/workspace/classloader/ClassLoaderTest.php on line 7

我必須簡單地接受,這是不可行的?

+0

可能有一個解決方法(通過外部解釋器reinvoke)。但這不是真正的單位測試要完成的。 (爲了簡單與PHPT結合) – mario

回答

4

調用class_exists(),它會嘗試自動載入該類,如果無法自動載入,則返回布爾值false。

http://php.net/manual/en/function.class-exists.php

+0

Robert似乎是最乾淨的選擇。我只是使用assertFalse(class_exists('Foo'))來實現同樣的事情。謝謝! –

1

看起來不可能發現致命錯誤。因此,而不是在__autoload中使用,要求您可以使用包含if語句並生成特定的異常。

2

要測試類intantiated與否,你可以簡單地做線沿線的東西:

try { 
    if(!class_exists("Foo")) 
      throw new Exception("Foo does not exist."); 
}catch(Exception $e){ 
    $e->showMessage(); 
} 

此外,如果您希望測試時,它實際上是引用它的存在(並且您不希望先執行class_exists),您可以在AutoLoader中執行此操作。我在下面進一步介紹了這一點,以及一個示例死亡聲明。

注意事項自動加載磁帶機

現在,可能是題外話,如果你希望能夠動態地包括一類不具有明確引用它,你可以通過實例化一個自動加載器。 AutoLoaders在引用類時查找類文件,然後在嘗試使用它之前將其包含在內。

因此,例如,您需要在您的Test.php文件中包含AutoLoader.php,以及使用該類的所有其他文件。這個文件會根據需要包含其他文件。

要做到這一點,你需要設置你的AutoLoader.php文件。它需要看起來像這樣:

// This tells PHP what to use to load the functions 
ini_set('unserialize_callback_func', '__autoload'); 

// Create an array pairing class names to their file include path 
$myClasses = array("Foo" => "Foo.php", "Bar" => "Bar.php"); 

class AutoLoader { 

    static function autoload($class){ 
     if(!in_array($class, $myClasses)) 
      die("The class {$class} doesn't exist!"); 
     require($myClasses[$class]); 
    } 

} 

if(function_exists('spl_autoload_register')) { 
    spl_autoload_register(array('AutoLoader', 'autoload')); 
} else { 
    function __autoload($className){ 
     # When called, load a previously unloaded class 
     AutoLoader::autoload($className); 
    } 
}