简体   繁体   中英

Job not being dispatched in test

I'm using laravel 8 and Laravel Sail.

I'm trying to test a email that is being sent from a job but is not being sent, no matter what I do. Here's my code

Bus::fake();
Mail::fake();
TheProductDoesNotExists::dispatch($this->channel, $document['product'], $document['name']);
Event::assertDispatched(TheProductDoesNotExists::class);
Mail::assertSent(ProductMissing::class);

And I get

The expected [App\Mail\ProductMissing] mailable was not sent.
  Failed asserting that false is true.

Inside the Job I even have a logger in the handle method but nothing is logged

public function handle()
    {
        logger('from the job');
        $alertTo = 'test@test';
        Mail::to($alertTo)->send(
            new ProductMissing($this->product, $this->orderName)
        );
    }

And nothing. Any help would be really appreciated! Thanks

When you write Queue::fake() or Bus::fake() , the framework will replace a real queue (redis, database...) with a SIMPLE ARRAY. All the jobs will be stored in that array and they WILL NOT be executed. The array is used for later assertations. So in your code:

Bus::fake();
Mail::fake();
TheProductDoesNotExists::dispatch($this->channel, $document['product'], $document['name']);
Event::assertDispatched(TheProductDoesNotExists::class);
Mail::assertSent(ProductMissing::class);

Because the TheProductDoesNotExists is not even executed, then no email is captured and the last line failed.

You can only test one of those two.

Bus::fake();
TheProductDoesNotExists::dispatch($this->channel, $document['product'], $document['name']);
Bus::assertDispatched(TheProductDoesNotExists::class);

Or:

Mail::fake()
TheProductDoesNotExists::dispatchNow($this->channel, $document['product'], $document['name']);
Mail::assertSent(ProductMissing::class);

Not both at the same time.

For better understanding, I recommend read the Illuminate\Support\Testing\Fakes\QueueFake from the Laravel source code.

Faking Queues

You may use the Queue facade's fake method to prevent queued jobs from being pushed to the queue. Most likely, it is sufficient to simply assert that Laravel was instructed to push a given job to the queue since the queued jobs themselves may be tested in another test class.

After calling the Queue facade's fake method, you may then assert that the application attempted to push jobs to the queue:

<?PHP

namespace Tests\Feature;

use App\Jobs\AnotherJob;
use App\Jobs\FinalJob;
use App\Jobs\ShipOrder;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
 use Illuminate\Support\Facades\Queue;
 use Tests\TestCase;

class ExampleTest extends TestCase
{
    public function test_orders_can_be_shipped()
    {
        Queue::fake();

        // Perform order shipping...

        // Assert that no jobs were pushed...
        Queue::assertNothingPushed();

        // Assert a job was pushed to a given queue...
        Queue::assertPushedOn('queue-name', ShipOrder::class);

        // Assert a job was pushed twice...
        Queue::assertPushed(ShipOrder::class, 2);

        // Assert a job was not pushed...
        Queue::assertNotPushed(AnotherJob::class);
    }
}

You may pass a closure to the assertPushed or assertNotPushed methods in order to assert that a job was pushed that passes a given "truth test". If at least one job was pushed that passes the given truth test then the assertion will be successful:

Queue::assertPushed(function (ShipOrder $job) use ($order) {
    return $job->order->id === $order->id;
});

If you only need to fake specific jobs while allowing your other jobs to execute normally, you may pass the class names of the jobs that should be faked to the fake method:

public function test_orders_can_be_shipped()
{
    Queue::fake([
        ShipOrder::class,
    ]);

    // Perform order shipping...

    // Assert a job was pushed twice...
    Queue::assertPushed(ShipOrder::class, 2);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM