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

ahinkle's avatar

Mock a service on a Job?

Hi, I'm attempting to write a test and mock the YouTube service. Full disclosure: new to the mockery library.

I'm using the Laravel YouTube library.

I'm attempting to mock the Youtube::searchAdvanced call, not actually to call the Youtube API. Some online resources say to add a 'Youtube' class in the job's constructor. Is that the only way? I find it strange to edit my job's code just for the ability to mock and add a test but perhaps I'm wrong and it's the standard. Any help or tips would be much appreciated!

    /**
     * Execute the job.
     */
    public function handle(): void
    {
        // use Alaouy\Youtube\Facades\Youtube;
        $upcoming = collect(Youtube::searchAdvanced([
            'type' => 'video',
            'eventType' => 'upcoming',
            'part' => 'id, snippet',
            'channelId' => config('youtube.channel_id'),
            'maxResults' => 50,
        ]));

        if ($upcoming->count() === 0) {
            tap($this->notifyOnJobFailure(), fn () => throw new \Exception('No upcoming livestreams found.'));
        }

        $sunday = $this->firstLivestreamByDate($this->upcomingSunday(), $upcoming);
        $wednesday = $this->firstLivestreamByDate($this->upcomingWednesday(), $upcoming);

        if ($sunday->count() > 0) {
            cache()->put('livestream.sunday', $sunday->first()?->id?->videoId, now()->addWeek());
        }
        if ($wednesday->count() > 0) {
            cache()->put('livestream.wednesday', $wednesday->first()?->id?->videoId, now()->addWeek());
        }

        if ($sunday->count() === 0 || $wednesday->count() === 0) {
            tap($this->notifyOnJobFailure($upcoming), fn () => throw new \Exception('Could not find upcoming livestreams for Sunday and/or Wednesday.'));
        }
    }
it('updates livestream links from YouTube', function () {
    // use Alaouy\Youtube\Facades\Youtube;
    Youtube::shouldReceive('searchAdvanced')->andReturn($this->fakeResponse());

    $job = new \App\Jobs\Livestream\UpdateUpcomingLivestreamJob();
    $job->handle();

    // Perform assertions...
});

0 likes
3 replies
louisph's avatar

Hi @ahinkle,

I'm using https://github.com/php-vcr/php-vcr, it seems to be, for me, the easiest way to catch third party API calls. The principle is simple, the "package" listen every outgoing request/response and save it in a yaml or json file. When you start the test the next time the file is already created, if the request match with request in this yaml file, it will get response from it instead of making a request to the third party.

2 likes
tisuchi's avatar
tisuchi
Best Answer
Level 70

@ahinkle How about this?

it('updates livestream links from YouTube', function () {
    // Mock the response from YouTube's searchAdvanced method
    Youtube::shouldReceive('searchAdvanced')
        ->once() // Ensure this method is called only once
        ->andReturn($this->fakeResponse());

    // Dispatch the job
    $job = new \App\Jobs\Livestream\UpdateUpcomingLivestreamJob();
    $job->handle();

    // Perform further assertions...
});

3 likes

Please or to participate in this conversation.