如何使用phpunit防止模型事件被触发?

Ale*_*dis 9 testing phpunit laravel laravel-4 laravel-5

我想阻止诸如"创建"之类的模型事件.使用phpunit测试我的应用程序时"更新"等.

在Laravel的文档中,它说你可以通过使用来防止事件被触发

$this->expectsEvents(App\Events\UserRegistered::class);

但在我的情况下,我没有期望的课程.

即使我$this->withoutEvents();用来阻止所有事件,也会触发雄辩的事件.

我怎样才能阻止雄辩的事件呢?

Paw*_*zad 10

展望Laravel Api Model::flushEventListeners()应该"删除该模型的所有事件监听器".

编辑

您可以在此基础上编写自定义方法:

public static function flushEventListeners()
{
    if (! isset(static::$dispatcher)) {
        return;
    }
    $instance = new static;
    foreach ($instance->getObservableEvents() as $event) {
        static::$dispatcher->forget("eloquent.{$event}: ".get_called_class());
    }
}
Run Code Online (Sandbox Code Playgroud)

这样的事情可能是:

public static function flushEventListenersProvided($events)
{
    if (! isset(static::$dispatcher)) {
        return;
    }
    $instance = new static;
    foreach ($instance->getObservableEvents() as $event) {
        if(in_array($event, $events)){
          static::$dispatcher->forget("eloquent.{$event}: ".get_called_class());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

并且可能将其作为特征添加到模型中,或者将所有模型扩展的基础模型添加到模型中.此代码未经测试,但应该让您了解如何完成此操作.


Jef*_*ett 7

如果你真的只是想禁用模型的观察者,例如creatingcreatedupdated等,那么你可以调用模型的 fa\xc3\xa7ade 方法unsetEventDispatcher.

\n\n

例如,您可以将其放置在测试类的setUp方法中。而且您不必重置它,tearDown因为框架会在下setUp一个测试中自动执行此操作。

\n\n
protected function setUp(): void\n{\n    parent::setUp();\n    App\\MyModel::unsetEventDispatcher();\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果您希望这是暂时的,请查看withoutEventDispatcher.

\n\n

您也可以在完成业务后将getEventDispatcher其保存到临时变量中,如本答案所示: /sf/answers/3591122741/setEventDispatcher

\n


小智 1

查看类shouldReceive的方法Model。基本上Model班级延伸了Mockery。这是一个假设您有一个类的示例Car

Car::shouldReceive('save')->once();
Run Code Online (Sandbox Code Playgroud)

这不会访问数据库,而是使用模拟。您可以在这里找到有关 Laravel 测试的更多信息:http://laravel.com/docs/4.2/testing

希望这可以帮助。