Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

omer_hamza's avatar

How can I test Laravel Jobs

I have a job that will send an HTTP request and if it fails it will try for the next 2 times, if it still fails I will send a log to the MS Teams channel. this is my job class

<?php

namespace App\Jobs;

use Exception;
use Throwable;
use Illuminate\Bus\Queueable;
use App\Services\MsTeamsService;
use Illuminate\Support\Facades\Http;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

class ReadyCardJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    public $tries = 3;

    /**
     * Create a new job instance.
     */
    public function __construct()
    {}

    /**
     * Execute the job.
     */
    public function handle(): void
    {
        $payload = [...];

        $response = Http::withBasicAuth('username', 'password')
            ->withHeaders(['Content-Type' => 'application/xml'])
            ->send('POST', '/my-url', ['body' => $payload]);

        if (!in_array($response->getStatusCode(), [200, 201]))
        {
            throw new Exception("status code:  " . $response->getStatusCode());
        }
    }

    public function failed(Throwable $exception): void
    {
        (new MsTeamsService)->send('Error', $exception->getMessage());
    }
}

As I tested it manually it is working fine but now I want to write those test cases

  • when the job fails on the first try and success on the second one, the MS Teams message should not be sent
  • The job failed all three times and the message was sent.

I know I could use a foreach and do it there but I want to use the Laravel build-in function instead of creating customer logic.

0 likes
3 replies
omer_hamza's avatar

@martinbean I already did that, but the problem is there will be two HTTP requests if the job fails (I mean when the code throws the exception) and in the test cases I have to use $this->expectException(Exception::class) and it will not let me to check if the second request was sent or not.

Please or to participate in this conversation.