2013-09-25 67 views
1

我一直試圖使用Mockery來聲明,在拋出異常時從另一個方法內調用方法。因此,作爲一個例子:PHP嘲笑不從模擬內部調用模擬方法

public function testOtherMethodIsCalled() { 

    $client = m::mock('Client'); 
    $client 
     ->shouldReceive('getFoo') 
     ->andThrow(new FooNotAvailableException); 

    $controller = m::mock('Controller[otherMethod]'); 
    $controller 
     ->shouldReceive('otherMethod') 
     ->once(); 

    $controller->setClient($client); 
    $controller->firstMethod(); 
} 

顯然,名稱已被簡化,但這是行其他各方面我有什麼相同的線。在代碼中,當FooNotAvailableException被捕獲時,我將呼叫返回otherMethod()

的問題是,當運行它,我得到這個錯誤:

Mockery\CountValidator\Exception: Method otherMethod() from Controller should be called exactly 1 times but called 0 times.

這是因爲內部原,unmocked otherMethod()被調用。如果我從測試內部調用它,像這樣:

$controller->otherMethod(); 

測試通過。

爲什麼會這樣,我該如何爲我想要測試的內容編寫測試?

+0

您的示例缺少'Client'和'Controller'的類定義。 Stackoverflow要求你證明一個自包含的例子,如果你沒有提供這些定義,我們可以說這個方法沒有被缺少的定義調用。 – hakre

回答

0

很難說沒有完整的源代碼,但我相信這是正在發生的事情:

您的代碼:

$client = m::mock('Client'); 
$client 
    ->shouldReceive('getFoo') 
    ->andThrow(new FooNotAvailableException); 

到目前爲止好。沒問題。

$controller = m::mock('Controller[otherMethod]'); 
$controller 
    ->shouldReceive('otherMethod') 
    ->once(); 

$controller->setClient($client); 
$controller->firstMethod(); 

現在,我們遇到了一個問題。我假設被測試的代碼正在重定向到另一個URL。發生這種情況時,您將實例化另一個Controller。您實例化的Controller不會是由「m :: mock('Controller [otherMethod]')」實例化的Controller。所以,顯然這個嘲弄的實例永遠不會收到「otherMethod」。

根據被測代碼的實際寫入方式,正確測試方法可能是聲明Redirect :: to已從處理FooNotAvailableException的函數中調用。