我有一个使用Laravel的global event()函数在更改模型时触发单个事件的类。我能够防止在单元测试期间触发此事件的唯一方法是实际命名空间并在测试本身中声明一个新的event()函数,并使它不执行任何操作。它有效,但是对我来说似乎不是一个很好的解决方案。我查看了Laravel文档,发现有人在测试中成功使用了Event :: fake(),但是当我尝试这样做时,我得到了:
BadMethodCallException: Method Mockery_0_Illuminate_Contracts_Events_Dispatcher::until() does not exist on this mock object
我正在使用Laravel 5.4。有没有更清洁的方法来防止此事件在测试期间触发?我真的不喜欢声明一个空的命名空间event()函数的想法。
编辑:
我正在测试的类是UserDomain类。在逻辑的一部分中,它调用Laravel的global event()方法:
event(new RoleChanged($this->user));
为了抑制它在测试中的触发,我尝试了Event :: fake(),并且还尝试了使用特质WithoutEvents及其WithoutEvents()方法。这两种方法均无效,并且两次都发生了我上面提到的相同错误。
答案 0 :(得分:0)
您需要在测试中使用Illuminate\Foundation\Testing\WithoutEvents
特征。
<?php
namespace Tests\Unit;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithoutEvents;
use Illuminate\Foundation\Testing\RefreshDatabase;
class FooTest extends TestCase
{
use WithoutEvents;
}
答案 1 :(得分:0)
我阅读了更多有关Laravel单元测试中的模拟的文档,发现在测试开始时,我要做的就是这样:
$this->expectsEvents(RoleChanged::class);
这告诉框架确认发生了此事件,但实际上并未将其触发。谢谢大家的帮助。它使我找到了可行的解决方案。
答案 2 :(得分:0)
使用 Illuminate\Foundation\Testing\WithoutEvents
trait,并在任何测试之前放置 $this->withoutEvents()
。
<?php
namespace Tests\Unit;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithoutEvents;
use Illuminate\Foundation\Testing\RefreshDatabase;
class UsersTest extends TestCase
{
use WithoutEvents;
/**
* @test
*/
public function email_is_required()
{
$this->withoutEvents();
// assertions
}
}