2013-09-25 68 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的函数中调用。