是否有Laravel测试事件被解雇的次数?

时间:2016-03-28 11:25:47

标签: php laravel laravel-5

我使用基本PHPUnit配置文件和默认的TestCase.php文件。

我正在寻找一种方法来检查在测试期间是否多次触发事件。当前代码如下:

function test_fires_multiple_events()
{
    $this->expectsEvents(SomeEvent::class);
}

理想情况下,我想要:

function test_fires_multiple_events()
{
    $this->expectsEvents(SomeEvent::class)->times(3);
}

4 个答案:

答案 0 :(得分:4)

在遍历MocksApplicationServices中的代码之后,我能够捎带特征以及它在withoutEvents()方法时捕获的字段。

扩展名如下:

function test_fires_multiple_events()
{
    $this->withoutEvents(); // From MocksApplicationServices

    $c = collect($this->firedEvents)
                ->groupBy(function($item, $key) { return get_class($item); })
                ->map(function($item, $key) { return $item->count(); });

    $this->assertsEqual(3, $c->get(SomeEvent::class));

}

要逐步完成集合的操作:

1)collect($this->firedEvents):获取捕获的事件并将其存储在集合中。值得注意的是,MocksApplicationServices将每个事件推送到一个数组中,这意味着它已经保持计数。

2)groupBy(function($item, $key) { return get_class($item); }):按类名分组,这意味着我们现在有一组数组。

3)map(function($item, $key) { .. }:简单地计算孩子们。

这会产生如下结构:

Illuminate\Support\Collection (1) (
    protected items -> array (2) [
        'App\Events\SomeEvent' => integer 2
        'App\Events\SomeOtherEvent' => integer 1
    ]
)

修改 只是为了清理一下 - 您可以将以下内容添加到基本测试用例文件中:

public function assertEventFiredTimes($event, $count)
{
    $this->assertEquals(
        count(collect($this->firedEvents)
            ->groupBy(function($item, $key) { return get_class($item); })
            ->get($event, [])),
        $count
    );
}

然后在你的测试中:

$this->assertEventFiredTimes(SomeEvent::class, 3);

不要忘记添加withoutEvents()

答案 1 :(得分:2)

laracasts中的某个人遇到了同样的问题并找到了解决方案: https://laracasts.com/discuss/channels/general-discussion/testing-class-based-events-in-laravel-5

基本上:您只需要模拟Event调度程序以期望您正在使用的事件类。之后,您可以检查所需的一切。

答案 2 :(得分:1)

我认为您需要将事件调度程序注入您的类,然后模拟它,以便您可以执行以下操作:

$dispatcher->shouldReceive('fire')->with(SomeEvent::class)->times(3);

答案 3 :(得分:1)

Laravel让您了解事件伪造品:

Event::fake(MyEvent::class)

// ... 

// Pass integer as callback to assertDispatched
Event::assertDispatched(MyEvent::class, 3);

// Or use the undocumented method assertDispatchedTimes directly
Event::assertDispatchedTimes(MyEvent::class, 3)

代码:https://github.com/laravel/framework/blob/master/src/Illuminate/Support/Testing/Fakes/EventFake.php#L47-L79