【问题标题】:PHP Mockery not calling mocked method from within mockPHP Mockery 没有从模拟中调用模拟方法
【发布时间】:2013-09-30 20:34:21
【问题描述】:

我一直在尝试使用 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();

测试通过。

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

【问题讨论】:

  • 您的示例缺少ClientController 的类定义。 Stackoverflow 要求您证明一个自包含的示例,如果您不提供这些定义,我们只能说缺少的定义不会调用该方法。

标签: php unit-testing phpunit mockery


【解决方案1】:

没有完整的代码源很难说,但我相信这就是正在发生的事情:

您的代码:

$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。发生这种情况时,您将实例化另一个控制器。您实例化的控制器不会是由“m::mock('Controller[otherMethod]')”实例化的控制器。因此,显然模拟实例永远不会收到“otherMethod”。

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

【讨论】:

    猜你喜欢
    • 2013-11-04
    • 2015-04-09
    • 2014-08-24
    • 2022-01-04
    • 2018-07-02
    • 2014-01-09
    • 1970-01-01
    • 2018-03-26
    • 2016-03-31
    相关资源
    最近更新 更多