【问题标题】:Laravel Event MockingLaravel 事件模拟
【发布时间】:2018-10-23 14:34:27
【问题描述】:

我对此代码进行了测试

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;
});

我的 EventServiceProvider 如下所示:

   protected $listen = [
        \App\Events\PaymentWasCompleted::class => [
            \App\Listeners\GenerateInvoice::class,
        ]
    ];

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);
    }

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

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

我不确定这是为什么。

我也试过

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

同样的问题。

【问题讨论】:

  • 我也有同样的问题。我不知道如何测试触发侦听器的事件,并且我花了很多时间尝试。测试事件很容易(使用您使用的方法)。测试处理程序很容易,只需模拟一个事件并用它实例化一个侦听器并调用->handle()。但是测试一个事件是否真的触发了监听器——我不知道该怎么做。
  • 我认为您需要进行 2 次不同的测试。一个只是伪造事件,第二个是伪造队列。假货将检查事件是否被触发,仅此而已。它对您的预期行为是什么或应该触发什么操作不感兴趣
  • @devk:是的,我知道,但我想确保监听器被正确触发。很奇怪。 @usrNotFound:你到底是什么意思?你的意思是我应该删除Event::fake();如果我想测试监听器是否被正确触发?

标签: php laravel laravel-5 phpunit


【解决方案1】:

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

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

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

所以,首先测试:

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;
});

第二次测试:

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;
});

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-10-20
    • 2010-11-20
    • 2011-02-01
    • 2011-05-19
    • 2012-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多