2011-05-19 37 views
2

我想測試一個自定義的錯誤處理類,我放在一起,但這本身就帶來了一些問題。PHPunit - 測試一個自定義的錯誤處理類

首先,由於在測試中設置自定義error_handler會覆蓋PHPUnits error_handling,因此每次更改爲自定義實現並進行測試時,都必須調用restore_error_handler(),以便後續測試具有phpunits error_handling。雖然我承認沒有嘗試過,也許PHPUnit在每次測試後都會重置自己,我有點懷疑它。

我有不同的配置來進行測試,在不同的條件下,即E_ERROR,E_WARNING等。

然後我就嘲笑error_handler的想法,但我仍然在嘲笑測試方面相當環保。快速谷歌搜索讓我找到了類似的做法,這裏的想法修改和實施的方式,可能適合我的需要...

//Create mock with error_handler method 
$errorH = $this->getMock ('ErrorHandler', array ('error_handler')); 

// error handler should be called at least once 
$errorH->expects ($this->atLeastOnce())->method ('error_handler'); 

// Mock will need to be configured (here?) and tested 
// against specific error_handling settings 
// not implemented yet nor needed for this post. 

//set mock as error handler for duration of this test 
set_error_handler (array($errorH, 'error_handler')); 

//test current mock error handler configuration 
// for different conditions-> NOTICE/WARNING/ERROR 

// Give phpunit's toy back! 
restore_error_handler(); 

這是一種有效的方法?

回答

8

有沒有必要測試PHP的set_error_handler()函數。你只關心你的錯誤處理類的工作。將測試PHP解釋器留給PHP開發人員。 :)像任何其他類一樣對待你的類:實例化它並調用它的方法,傳遞參數來測試不同的條件。

例如,假設你的錯誤處理程序看起來是這樣的:

class ErrorHandler 
{ 
    private $logger; 

    private $mode; 

    public function __construct($mode, $logger) { 
     $this->mode = $mode; 
     $this->logger = $logger; 
    } 

    public function handleError($code, $message, $file='', $line=0, $context=array()) { 
     if ($code = E_WARNING && $this->mode == 'dev') { 
      // warnings are logged in development mode 
      $this->logger->log($message, Logger::WARN); 
     } 
     ... 
    } 
} 

您可以使用一個模擬記錄儀來測試上面的一個特性,而不必調用set_error_handler()或觸發一個實際的PHP錯誤。取而代之的是,撥打電話到您的錯誤處理程序,就像PHP將在這些條件下做到:

function testWarningsAreLoggedInDevelopment() { 
    $logger = $this->getMock('Logger', array('log')); 
    $logger->expects($this->once()) 
      ->method('log') 
      ->with('message', Logger::WARN); 
    $handler = new ErrorHandler('dev', $logger); 
    $handler->handleError(E_WARNING, 'message'); 
} 

的美妙之處在於,如果你的錯誤處理程序觸發PHP錯誤,由於一個bug,PHPUnit的將捕捉到它並測試失敗。如果用自己的代碼替換PHPUnit的處理程序,那麼隨着PHP一遍又一遍地調用處理程序,直到解釋程序因堆棧溢出或內存不足而死亡時,您可能會進入無限循環。

+0

我試圖測試不是set_error_handler本身,而是由set_error_handler加載的自定義錯誤處理程序。 – stefgosselin 2011-05-19 23:00:40

+3

@stefgosselin - 我的意思是說PHP將使用'set_error_handler()'調用你指定的方法,並且不需要測試這個方面。相反,編寫測試以直接調用該方法並傳入適當的參數。我會在我的答案中添加一個示例來說明。 – 2011-05-20 01:44:54

+0

Aaaah!我剛看到光!感謝大衛,這真是太棒了。 – stefgosselin 2011-05-20 03:28:59