【问题标题】:Assert that a Mock Facade was called/run in Laravel 4断言在 Laravel 4 中调用/运行了 Mock Facade
【发布时间】:2014-12-04 13:39:03
【问题描述】:

我开始使用Laravel 4.2PHPUnitMockery 编写测试。

如何断言我正在测试的控制器调用/运行了模拟外观?

例如,我对Queue 有以下嘲讽。我的控制器没有返回任何与Queue::push() 相关的信息,那么有没有办法可以断言它触发了Queue::push()

Queue::shouldReceive('push')->once();
Queue::shouldReceive('connected')->once();

如果我在控制器中注释掉 Queue::push()Queue::shouldReceive 会引发异常:

Mockery\Exception\InvalidCountException:来自 Mockery_0_Illuminate_Queue_QueueManager 的方法 push() 应该准确调用 1 次,但调用了 0 次。

断言 Mock Facade 运行的唯一方法是执行以下操作吗?

    $queuepushran = false;
    try {
        Queue::shouldReceive('push')->once();
        Queue::shouldReceive('connected')->once();
        $queuepushran = true;           
    } catch (\Mockery\Exception\InvalidCountException $e) {
        //Queue threw an exception
        $queuepushran = false;
    }
    $this->assertTrue($queuepushran);

【问题讨论】:

    标签: php unit-testing laravel phpunit mockery


    【解决方案1】:

    您在使用模拟对象和期望来测试这一点方面走在了正确的轨道上,但这并不是应该如何使用模拟的。您的代码 sn-p 似乎缺少实际调用控制器的信息,因此很难准确判断发生了什么,但我将简单介绍一个完整的示例。

    您想测试当您的控制器方法运行时,Queue 外观的push()connected() 方法分别被调用一次。我们要做的是使用 Laravel 酷炫的外观功能,将 Queue 外观背后的真实 QueueManager 类替换为一个模拟对象,这样当控制器调用 Queue::push(..) 时,它将调用我们的模拟对象。

    那么,让我们开始构建测试吧:

    public function testSomeControllerMethodCallsTheQueue()
    {
        Queue::shouldReceive('push')->once();
        Queue::shouldReceive('connected')->once();
    }
    

    我们现在已经将真正的 QueueManager 换成了我们的模拟队列管理器,并设置了我们期望它们被调用的方式。由于每个测试应该只做一件事,我们现在已经完成了“安排”测试所需的一切。

    接下来,我们需要通过调用控制器来“行动”。

    public function testSomeControllerMethodCallsTheQueue()
    {
        Queue::shouldReceive('push')->once();
        Queue::shouldReceive('connected')->once();
    
        $this->action('GET', 'YourController@method');
    }
    

    最后一步是“断言”,但我们实际上不需要做任何事情。如果我们的 Mockery 期望得到满足,测试将完成并变为绿色。如果我们的 Mockery 期望没有得到满足,就会抛出异常并且测试会变红。 Mockery 抛出的异常旨在成为您的测试失败的原因,您不需要在将返回值或响应与您的期望进行比较时进行断言——Mockery 会处理所有这些。

    【讨论】:

    • Queue::push running 并不是我想从该调用中做出的唯一断言。 Mockery 抛出异常不会阻止我的其余断言运行吗?我不想让 PHPUnit 的 stopOnFailure="false" 选项控制我的所有断言是否都运行,而不是抛出异常吗?
    • 是的,但我想说最常见的是让您的测试在失败时停止。当它已经变红时,您不会浪费时间运行整个测试套件(一旦您有数百个测试可能会花费相当长的时间)。
    猜你喜欢
    • 2014-12-08
    • 2015-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-24
    • 1970-01-01
    • 2017-03-01
    相关资源
    最近更新 更多