longestdrive's avatar

Test a laravel job calls another class

Hi. I'm trying to test that a job calls another class and am confused about the approach to take: My job simply calls a class to handle the type of email to send to a user.

Here's my job:

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

    /**
     * The number of times the job may be attempted.
     *
     * @var int
     */
    public int $tries = 3;

    /**
     * The number of seconds the job can run before timing out.
     *
     * @var int
     */
    public int $timeout = 240;

    private League $league;
    private Fixture $fixture;
    private FixtureReminderEmail $fixtureReminderEmail;

    /**
     * Create a new job instance.
     */
    public function __construct(League $league)
    {
        $this->league = $league;

        $this->fixtureReminderEmail = app()->make(FixtureReminderEmail::class, ['league'=>$this->league]);

    }

    /**
     * Get the tags that should be assigned to the job.
     *
     * @return array
     */
    public function tags()
    {
        return ['fixtureReminderEmail'];
    }

    /**
     * @return void
     * @throws Exception
     */
    public function handle(): void
    {

        $counter = $this->fixtureReminderEmail->handle();

        Log::info($counter . " Fixture " . Str::plural('reminder', $counter) .  "sent");
    }
}

In my test I'm trying to do this:

class SendFixtureReminderJobTest extends TestCase
{
    use RefreshDatabase;
    use WithFaker;

    private $adminUser;

    protected function setUp(): void
    {
        parent::setUp();
        $this->seed();
//
        $this->adminUser = User::factory()->create(['admin' => 1]);
    }

    /**
     * @test
     * @covers SendEclecticUpdateEmailJob::handle
     * @description:
     */
    public function testHandle()
    {
        Queue::fake();

        $league = League::factory()->matchplay()->create();

        $mock = $this->mock(FixtureReminderEmail::class, function($mock) use ($league) {
            $mock->shouldReceive('handle')
                ->with($league)
                ->once();

        });

        $this->withoutExceptionHandling();

       $instance = resolve(SendFixtureReminderEmailJob::class, ['league' => $league]);

        app()->call([$instance, 'handle']);

        Queue::assertPushed(FixtureReminderEmail::class);
    }
}

The test fails on the mock saying the mock method was not called.

If I remove the mock and run the test again then the test fails as the job class was not pushed to the queue.

So: What is the best way to test that this job calls FixtureReminderEmail::class?

0 likes
0 replies

Please or to participate in this conversation.