Unit testing 解释Laravel 5.1关于注册事件处理程序和测试的问题;“期望值”;

Unit testing 解释Laravel 5.1关于注册事件处理程序和测试的问题;“期望值”;,unit-testing,laravel,events,laravel-5.1,Unit Testing,Laravel,Events,Laravel 5.1,[前言:我解决了我的根本问题,这个问题是为了理解它最初为什么会发生] 我一直在调试一个测试用例,其中我通过$this->expectsEvents(App\Events\MyTestEvent::class)注册了一个事件预期。即使事件侦听器的代码已运行,测试仍不断给我以下错误: 异常:未触发以下事件: [应用程序\事件\ MyTestEvent] 通过大量的尝试和错误,当同时使用两种不同的注册事件处理程序的方法(在EventServiceProvider.php中)时,似乎出现了问题。请参见下

[前言:我解决了我的根本问题,这个问题是为了理解它最初为什么会发生]

我一直在调试一个测试用例,其中我通过
$this->expectsEvents(App\Events\MyTestEvent::class)
注册了一个事件预期。即使事件侦听器的代码已运行,测试仍不断给我以下错误:

异常:未触发以下事件: [应用程序\事件\ MyTestEvent]

通过大量的尝试和错误,当同时使用两种不同的注册事件处理程序的方法(在EventServiceProvider.php中)时,似乎出现了问题。请参见下面的案例1,这是我注册事件处理程序的原始代码。如果我将
auth.login
处理程序移动到
$listen
数组(请参见案例2),我的测试工作正常,问题就解决了

问题:

  • 在案例1中,我是否做错了什么?或者
  • 这是已知的/预期的行为吗?或者
  • 这是Laravel事件处理程序中的错误吗
谢谢你的帮助和时间


案例1(原始代码,MyTestEvent的expectsEvent()测试失败)


案例2(修改代码,MyTestEvent的expectsEvent()成功)


我认为问题在于你的测试预期的是一个不同的事件。您是否混淆了要测试的事件?这一行:

$this->expectsEvents(App\Events\MyTestEvent::class);
正在等待在
App\Events\MyTestEvent
类中激发的事件。在案例1和案例2中与之关联的侦听器是
App\Listeners\TestListener
。(从您提供的代码中不清楚是否曾经触发过
MyTestEvent
,这可以解释您看到的异常。)

但是,您为其注册侦听器的事件是
auth.login
。在案例1中,侦听器是一个匿名函数,在案例2中,侦听器由
App\Listeners\LoginListener
类实例化。要对此进行测试,测试代码应如下所示:

$this->expectsEvents('auth.login');
假设触发了
auth.login
事件,您不应该期望监听器代码在之后执行


我仍然觉得奇怪的是,在一种情况下,
MyTestEvent
似乎会触发,而在另一种情况下则不会,因为它似乎与您正在收听的事件都没有关系。也许在您的各种事件和侦听器类中发布代码会让事情变得更清楚。

谢谢。我的测试应该激发+期望类的偶数
MyTestEvent
。“auth.login”事件的注册似乎是测试行为的一部分。我不是在测试auth.login,它只是导致我出现问题的原因。在案例1中,
expectsEvent
似乎无法正常工作,因为我的处理程序启动了,然后测试用例就好像从未看到过事件一样。我最好的猜测是,有什么东西让Laravel感到困惑,导致我的测试用例预期的
MyTestEvent
没有正确注册。您是否尝试过使用传递到
boot()
$events
变量,而不是
Event
facade?i、 例如,
$events->listen('auth.login',…)
而不是
Event::listen('auth.login',…)
文档中的示例就是这样做的,但我不确定为什么会有不同。绘图变厚:使用
$events
而不是外观会导致一切按预期工作。我想知道为什么。另一个测试:当你使用facade时,你是否也有
use-Event在类定义之前的文件顶部?在早期版本的Laravel中,使用facade不需要做任何特殊的事情,但我在5.1中发现,必须通过use语句显式地让类知道您将使用facade。没有
使用事件将导致facade无法访问允许您访问已注册事件的基础
DispatcherContract
$this->expectsEvents(App\Events\MyTestEvent::class);
$this->expectsEvents('auth.login');