Ranx99's avatar

How to test a failing job code

I have this job:

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

    public $file;

    public function __construct(File $file)
    {
        $this->file = $file;
    }

    public function handle()
    {
        $this->file->update([
            'status' => 'procssing',
        ]);

        $this->start();

        $this->file->update([
            'status' => 'success',
        ]);
    }

    public function failed(Exception $exception)
    {
        $this->file->update([
            'status' => 'un-procssed',
        ]);
    }

    protected function start()
    {
        return true;
    }
}

I am trying to test the code in the failed method:

/** @test */
public function it_will_set_status_to_un_procssed_when_failing()
{
    $file = factory(File::class)->create();

    $mock = Mockery::mock(ProcessFileJob ::class, [$file])->shouldAllowMockingProtectedMethods()->makePartial();
    $mock->shouldReceive('start')->once()->andThrow(new CustomException('test'));

    $mock->handle($file);

    $this->assertEquals('un-processed', $file->fresh()->status);
}

but this will always throw the CustomException and the test will fail.. even If I use withExceptionHandling method. I just want to test the code in the failed method to make sure when the job is failed the status of the file will change.

0 likes
3 replies
adamprickett's avatar

Since you're calling handle() directly and not within the job processing scope, there's no exception handling to call failed() after the exception is thrown.

Instead of $mock->handle($file), you could try calling app(Dispatcher::class)->dispatchNow($mock)

Ranx99's avatar

dispatchNow doesnt work here also:

The failed method will not be called if the job was dispatched using the dispatchNow method.

I tried to use dispatch($mock), but I am getting Exception: Serialization of 'ReflectionClass' is not allowed error.

martinbean's avatar

@ranx99 You’re mocking the wrong object. If you’re trying to test the handle method is called on your job when a bad file is passed to it, then mocking the job class itself isn’t going to help you.

Instead, you need to mock the file, have it trigger an exception, and then assert your failed method is called instead.

Please or to participate in this conversation.