My Laravel 5.5 application has a Product
model. The Product
model has a dispatchesEvents
property that looks like this:
/*
Running artisan queue:work
won't solve the issue because when testing, Laravel is configured to use the sync
driver, which just runs jobs synchronously in your tests. I am not sure why the job is not being pushed, though I would guess it has to do with Laravel handling events differently in tests. Regardless, there is a better approach you can take to writing your tests that should both fix the issue and make your code more extendable.
In your ProductTest
, rather than testing that a_created_product_is_pushed_to_the_queue_so_it_can_be_added_to_magento
, you should simply test that the event is fired. Your ProductTest
doesn't care what the ProductCreated
event is; that is the job of a ProductCreatedTest
. So, you can use Event Faking to change your test a bit:
/** @test */
public function product_created_event_is_fired_upon_creation()
{
Event::fake();
factory(Product::class)->create();
Event::assertDispatched(ProductCreated::class);
}
Then, create a new ProductCreatedTest
to unit test your ProductCreated
event. This is where you should place the assertion that a job is pushed to the queue:
/** @test */
public function create_product_in_magento_job_is_pushed()
{
Queue::fake();
// Code to create/handle event.
Queue::assertPushed(CreateProductInMagento::class);
}
This has the added benefit of making your code easier to change in the future, as your tests now more closely follow the practice of only testing the class they are responsible for. Additionally, it should solve the issue you're having where the events fired from a model aren't queuing up your jobs.