Laravel 事件模拟

The*_*Guy 3 php phpunit laravel laravel-5

我对此代码进行了测试

Event::fake();

Queue::fake();

// Fake an order
$order = factory(Order::class)->make();

event(new PaymentWasCompleted($order));

Event::assertDispatched(PaymentWasCompleted::class, function ($e) use ($order) {
    return $e->order->id === $order->id;
});

Queue::assertPushed(GenerateInvoiceJob::class, function ($job) use ($order) {
    return $job->order->id === $order->id;
});
Run Code Online (Sandbox Code Playgroud)

我的 EventServiceProvider 看起来像这样:

   protected $listen = [
        \App\Events\PaymentWasCompleted::class => [
            \App\Listeners\GenerateInvoice::class,
        ]
    ];
Run Code Online (Sandbox Code Playgroud)

GenerateInvoice 侦听器如下所示:

   public function __construct()
    {
        $this->eventName = 'GenerateInvoice';
    }

 public function handle(PaymentWasCompleted $event)
    {
        // Access the order using $event->order
        $order = $event->order;

        $job = (new GenerateInvoiceJob($order, $this))->onQueue(app('QueueHelper')->getQueueName($this->eventName));
        $this->dispatch($job);
    }
Run Code Online (Sandbox Code Playgroud)

我希望测试通过,但它失败了:

未推送预期的 [App\Jobs\GenerateInvoiceJob] 作业。

我不确定为什么会这样。

我也试过

Queue::assertPushedOn(app('QueueHelper')->getQueueName('GenerateInvoice'), GenerateInvoiceJob::class, function ($job) use ($order) {
            return $job->order->id === $order->id;
        });
Run Code Online (Sandbox Code Playgroud)

同样的问题。

The*_*Guy 7

重新阅读文档后,很明显这是预期的行为。文档说

作为模拟的替代方法,您可以使用 Event 门面的 fake 方法来阻止所有事件侦听器的执行。

如评论中所述,我必须创建两个测试。一个用于确保事件已被触发并包含预期数据,第二个用于确保事件侦听器被触发。

所以,首先测试:

Event::fake();

$order = factory(Order::class)->make();

event(new PaymentWasCompleted($order));

Event::assertDispatched(PaymentWasCompleted::class, function ($e) use ($order) {
    return $e->order->id === $order->id;
});
Run Code Online (Sandbox Code Playgroud)

第二次测试:

Queue::fake();

$order = factory(Order::class)->make();

event(new PaymentWasCompleted($order));

Queue::assertPushed(GenerateInvoiceJob::class, function ($job) use ($order) {
    return $job->order->id === $order->id;
});
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,这个测试通过了。