我使用基本PHPUnit配置文件和默认的TestCase.php文件。
我正在寻找一种方法来检查在测试期间是否多次触发事件。当前代码如下:
function test_fires_multiple_events()
{
$this->expectsEvents(SomeEvent::class);
}
理想情况下,我想要:
function test_fires_multiple_events()
{
$this->expectsEvents(SomeEvent::class)->times(3);
}
答案 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)