ramytamer's avatar

Mocking the GuzlleHttp\Client class is not working

I have this controller:


<?php

namespace App\Http\Controllers;

use App\User;
use Illuminate\Http\Request;

class SomeController extends Controller
{
    protected $guzzle;

    public function __construct(\GuzzleHttp\Client $guzzle)
    {
        $this->guzzle = $guzzle;
    }


    public function index() {
        $url = "api.domain.com/{request()->token}";
        $this->guzzle->get($url);

        return 'welcome';
    }
}


When i try to test the functionality of the index page i of course i want to mock the get method and not actually fire it.

Also i want to make sure that the get method on guzzle has been called with the right url.

This is my test method

/** @test */
    public function it_tests_the_index_page()
    {   
        $token = 123456;
        $url = "api.domain.com/{$token}";
        $guzzle = Mockery::mock(\GuzzleHttp\Client::class);
        $guzzle->shouldReceive('get')
               ->with($url)
               ->andReturn('OK');

        $this->visit("/?token={$token}")
             ->see('welcome');
    }

When i run my test suite; guzzle fire the actual request with fake token i provided not the mocked method and of course the api returns an error because it's an invalid token. I just want to test that it get's the proper url.

0 likes
3 replies
ohffs's avatar
ohffs
Best Answer
Level 50

Maybe before the -visit() call do :

$this->app->instance('GuzzleHttp\Client', $guzzle);
1 like
ohffs's avatar

When you call the ->visit() you're asking laravel to make the controller, and it sees the controller needs a guzzle client - so it makes one of those too.

In this case you want laravel to use your mocked guzzle rather than making a new one, so that's why you tell it 'when you see something needs guzzle, use this instance' :-)

2 likes

Please or to participate in this conversation.