2014-02-14 60 views
7

當使用phpunit進行單元測試時,是否有任何方法對通過調用'error_log(「Message」)'創建的輸出運行測試?有沒有什麼辦法可以在PHPUnit測試中'expect'輸出到error_log?

示例代碼,我的一個功能測試信用卡用Luhn算法:

if($checkLuhn && ($this->_luhn_check($cardNumber) == false)) { 
    error_log(__METHOD__ . " cardNumber failed luhn algorithm check."); 
    return false; 
} 

$ checkLuhn是傳遞一個布爾值來判斷是否做了檢查,_luhn_check()返回如果真$ cardNumber通過。問題是,我在這個函數中有多個測試可以返回false。我可以對返回值使用assertEquals,但也想檢查錯誤發生的原因。

你可以重寫error_log或以某種方式在單元測試中抓取系統日誌輸出嗎?

+1

你的'$ this - > _ luhn_check($ cardNumber)'在那裏拋出一個異常嗎?如果是這樣,您可以獲得該異常並將其記錄在您的測試中。 – Jhn

+2

我認爲你錯過了一些關於你的錯誤檢測/日誌記錄的抽象層次。如果你使用一個類來記錄所有的錯誤,你只需在你的測試中嘲笑那個類。然後,您還要測試該課程,以檢查其是否按預期工作。你想在這裏測試的是錯誤被觸發,而不是觸發錯誤時會發生什麼。 – gontrollez

+0

我同意@gontrollez,絕對應該將代碼從代碼中抽象出來並作爲服務引入。您將能夠編寫更好(更簡單)的測試,另外您將獲得很大的靈活性並可以寫入多個日誌。 –

回答

6

有幾種不同的方式可以指示error_log()發送數據的位置。

首先就像error_log()發送一些地方一樣。一個例子是:

error_log('This is a message from error_log()', 3, '/dev/stdout'); 

它使用destination option for error_log()

另一種方法是覆蓋error_log ini setting in PHP。這看起來是這樣的:

$cur_error_log = ini_get('error_log'); 
ini_set('error_log', '/dev/stdout'); 
error_log('This is a message from error_log()'); 
ini_set('error_log', $cur_error_log); 

兩個選項我一般喜歡使用的error_log目的地選項()時可能。

從那裏你可以使用PHPUnit中的expectOutputString()來查找從error_log()發送的數據。

+0

因爲ini_set返回前一個值,所以不需要使用'ini_get':http://php.net/manual/en/function.ini-set.php – DanielM

0

您可以使用從Zend公司的uopz擴展超載喜歡這些功能。 我一直都在使用它們。這裏是一個例子:

/** 
* Requires the following set in php.ini: 
* - zend_extension=php_uopz.dll; 
* - uopz.overloads=1 
* 
* @author Aap Noot 
*/ 
class MyClass extends PHPUnit_Framework_TestCase { 
    public static $error_log = array(); 

    /** 
    * Overload error_log function 
    * @see PHPUnit_Framework_TestCase::setUpBeforeClass() 
    */ 
    public static function setUpBeforeClass() { 
     uopz_backup ("error_log"); 
     uopz_function ("error_log", function ($message, $message_type = null, $destination = null, $extra_headers = null) { 
      // We are only interested in the message 
      MyClass::$error_log[] = $message; 
     }); 
     parent::setUpBeforeClass(); 

    /** 
    * Restore function(s) 
    * @see PHPUnit_Framework_TestCase::tearDownAfterClass() 
    */ 
    public static function tearDownAfterClass() { 
     uopz_restore ("error_log"); 
     parent::tearDownAfterClass(); 
    } 

    /** 
    * Set up per test case 
    * @see PHPUnit_Framework_TestCase::setUp() 
    */ 
    protected function setUp() { 
     parent::setUp(); 
     MyClass::$error_log = array(); 
    } 

    /** 
    * Test error log 
    * MyClass::$error_log should be an array with the error message 
    */ 
    public function testErrorLog() { 
     // Test response 
     error_log("This message will be captured"); 

     // Test error log 
     $this->assertNotEmpty(MyClass::$error_log); 
    } 
} 
相關問題