Summer Sale! All accounts are 50% off this week.

drewdan's avatar
Level 15

Testing Guzzle Api Call

Hi All,

I am trying to do a feature test which will validate that a user can pass data to insightly CRM. However, I of course only want to mock this, and not ping Insightly everytime I run the script.

I figured I had to mock the client, pass this into the service container and I could then run my feature test, however, every time I do, it still hits the Insightly server.

/** @test */
    public function testStoreInsightly() {
        $client = $this->createMockClient(200, json_encode(['status' => 200]));
        $this->app->bind(Client::class, $client);


        $params = [
            '[email protected]' => [
            'method' => 'post',
            'route' => '/crms',
            'responseCode' => 302,
            'assertData' => '',
            'affectedTable' => '',
            'testData' => [
                    'crm' => 'insightly',
                    'key' => '0a71976b-bcb2-b8bd-221a-0cea63510721',
                ],
            ],
        ];
        $response = $this->featureTest($params);
    }

    public function createMockClient($status = 200, $body = '') {
        $mock = new MockHandler([
            new Response($status, [], $body),
        ]);
        $stack = HandlerStack::create($mock);
        return new Client(['handler' => $stack]);
    }

that is my test.

The feature test function it calls to run the test is:

protected function featureTest($testParams) {
        foreach ($testParams as $user => $params) {
            foreach ($params as $key => $param) {
                $$key = $param;
            }

            $this->signIn($user);
            $response = $this->$method($route, $testData);

            if ($assertData === true) {
                $this->assertDatabaseHas($affectedTable, $testData);
            } elseif ($assertData === false) {
                $this->assertDatabaseMissing($affectedTable, $testData);
            }
            $response->assertStatus($responseCode);
            //return($response);
        }
    }

I am unsure as to how to get this work. I thought mocking the Guzzle client would be it, but every time I get a response from the server.

Any advice or tips would be great!

0 likes
3 replies
ImanST's avatar

i guess you should use your GuzzleHttp\Client in construct of the main class and in your test, function createMockClient use : $this->app->instance('GuzzleHttp\Client', new Client(['handler' => $stack])); before calling API. i wish it can help you

1 like
martinbean's avatar
Level 80

@drewdan Mocking will only work if you then try and resolve the client instance via the container. If you’re just manually instantiating a client, then your mock won’t be used.

drewdan's avatar
Level 15

Hi Folks,

I should have really updated this post 2 years ago when I worked it out. Fortunately, I am not still stuck on it, lol!

It was indeed that I was not resolving the client from the container, so the mock made no difference. The project has now evolved, and we are using the Http facade instead, so mocking and testing is much easier.

Thank you both for your responses :)

Please or to participate in this conversation.