Search code examples
phplaravelqueuephpunitlaravel-artisan

handle queue:work using exec in test mode - Laravel


I am having trouble externally processing jobs on the queue while in test mode using PHPUnit. I have a job that writes a message to the the log file which is dispatched when I visit a route, I thought it could work like the way it does in development where there is a terminal window listening for work with php artisan queue:work and the other running server.

Test.php

public function testBasicTest()
{
    $message = "Sample message job " . date("l jS \of F Y h:i:s A");
    $filename = "laravel.log";
    $this->json('GET', route('test.test-try-log-job'), ['message' => $message]);
    $this->assertDatabaseHas('jobs', [
        'id' => 1,
    ]);

    exec('php artisan queue:work');  // Artisan::call("queue:work");

}

Controller

class TestController extends Controller
{
    public function tryLogJob(Request $request){
        dispatch(new TestJob($request->message))->onQueue('default');
        return response()->json(['success'=>true], Response::HTTP_OK);
    }
}

Job

class TestJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
    
    public $message;
    public function __construct($message)
    {
        $this->message = $message;
    }
    
    public function handle()
    {
        Log::info($this->message);
        sleep(5);
    }
}

when I use Artisan::call("queue:work"); the job is processed but when I use exec('php artisan queue:work');, it is not processed.

Is there a way I can get this to work? I really need to use the exec() function.


Solution

  • The phpunit.xml was configured to SQLite but the .env file was configured to MySQL.

    During the test the job was being added to SQLite and not MySQL on which exec('php artisan queue:work'); is run.

    I set the database variables in phpunit.xml to match those .env (MySQL) and the jobs are being handled correctly.