PHP Mockery没有在mock中调用mocked方法

时间:2013-09-25 09:56:54

标签: php unit-testing phpunit mockery

我一直在尝试使用Mockery断言在抛出异常时从另一个方法中调用一个方法。举个例子:

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:来自Controller的方法otherMethod()应​​该被调用1次但是被调用0次。

那是因为内部原始的,未被嘲弄的otherMethod()被调用。如果我在测试中调用它,就像这样:

$controller->otherMethod();

测试通过。

为什么会这样,我如何为我想要测试的内容编写测试?

1 个答案:

答案 0 :(得分: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”。

根据实际编写的测试代码的方式,测试它的正确方法可能是断言已从处理FooNotAvailableException的函数调用Redirect :: to。