7

According to the Laravel Documentation, I can use Queue::fake(); prevent jobs from being queued.

What is not clear how to test (PHPUnit) a few methods in the Job Class while it is not being queued.

For example:

class ActionJob extends Job
{
    public $tries = 3;
    protected $data;

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


    public function handle()
    {
        if ($this->data['action'] == "deleteAllFiles") {
            $this->deleteAllFiles();
        }
    }

    protected function deleteAllFiles()
    {
        //delete all the files then return true
        // if failed to delete return false
    }
}

Here is example I want to test deleteAllFiles() - do I need to mock it?

I'll-Be-Back
  • 10,530
  • 37
  • 110
  • 213
  • Have you tried to `pre` `var_dump` following with `die;`? You could add this in the function deleteAllFiles() before deleting anything. If you need an example just say, and ill write one. – Ronnie Oosting Sep 30 '17 at 13:57
  • 1
    @RonnieOosting I am talking about doing the test with phpunit. – I'll-Be-Back Sep 30 '17 at 14:51
  • Can you show us how you are calling the Job from your controller (or wherever else you're calling it from)? – tptcat Sep 30 '17 at 15:22
  • @tptcat It will be calling from the controller. eg: `dispatch(new ActionJob(['action' => 'deleteAllFiles']));` – I'll-Be-Back Sep 30 '17 at 15:31

1 Answers1

6

The idea of using the fakes is that they're an alternative to mocking. So, yes, if you want to mock that deleteAllFiles() was called, then I don't believe you can do that with the fake.

However, you can assert that a certain attribute exists on the job.

One thing, it's not in your example, but make sure your job is implementing \Illuminate\Contracts\Queue\ShouldQueue.

Something like this

<?php

namespace App\Jobs;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;

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

    public $tries = 3;

    public $data; // Make sure this public so you can access it in your test

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


    public function handle()
    {
        if ($this->data['action'] == "deleteAllFiles") {
            $this->deleteAllFiles();
        }
    }

    protected function deleteAllFiles()
    {
        // do stuff
    }
}

Then in your test:

// ActionJobTest.php
Queue::fake();

// Do some things to set up date, call an endpoint, etc.

Queue::assertPushed(ActionJob::class, function ($job) {
    return $job->data['action'] === 'deleteAllFiles';
});

If you want to assert on $data within the job, then you can make some other state change and assert on that in the Closure.

Side note: If the Job is Disptachable you can also assert like this:

// ActionJobTest.php
Bus::fake();

// Do some things to set up date, call an endpoint, etc.

Bus::assertDispatched(ActionJob::class, function ($job) {
    return $job->data['action'] === 'deleteAllFiles';
});
tptcat
  • 3,894
  • 2
  • 32
  • 51
  • Ah I see, it make sense now. Can you provide example of mocking `deleteAllFiles`() method assuming returned true and `handle()` has to be called. – I'll-Be-Back Sep 30 '17 at 16:19
  • 1
    In this approach, you assert on the data, not that specific methods are called. I'd post another question specifically about mocking since that isn't specifically tied to Laravel. For learning more about mocking, this helped me a lot: https://jtreminio.com/2013/03/unit-testing-tutorial-part-4-mock-objects-stub-methods-dependency-injection/ – tptcat Sep 30 '17 at 16:21
  • Thank you. It look like I will have to do something like `$job = new ActionJob(...); $job->handle();` in the Test. I thought `Queue::fake();` would call `handle()` automatically. – I'll-Be-Back Sep 30 '17 at 16:31
  • 1
    No. The main point of faking it is to assert that it is queued or dispatched. – tptcat Sep 30 '17 at 16:50