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

DreamyT's avatar

Trying to mock an http client that is inside a controller, using phpunit, but it doesn't work

I have to test the routes of a controller which uses Guzzle Wrapper as a client to get data from an API. The app uses Laravel as a framework.

This is the part of the code that gives me trouble in the controller's function I am currently testing:

public function addContacts(Request $request)
{
   ...
   $client = new GuzzleWrapper();
   $response = $client->post($uri, $data);
   if($response->getStatusCode() != 200) { 
      return response()->json("Problem getting data", 500);
   }
   ...
}

Now, what I have tried are getMockBuilder:

$mock = getMockBuilder(GuzzleWrapper::class)->onlyMethods(array('post'))->getMock();
$mock->expects($this->once())->method('post')->willReturn(response()->json([$responseData], 200));

Http::fake :

Http::fake(
   [$uri => Http::response([$responseData], 200)
);

Mockery :

$mockGuzzleClient = Mockery::mock(GuzzleWrapper::class);
$mockGuzzleClient->shouldReceive('post')
->andReturn(response()->json([$responseData], 200));

I also tried Mockery like this:

$mockGuzzleClient = Mockery::mock(GuzzleWrapper::class, function (MockInterface $mock){
   $mock->shouldReceive('post')
   ->andReturn(response()->json([$responseData], 200));
});

And like this:

$this->app->instance(
   GuzzleWrapper::class,
   Mockery::mock(GuzzleWrapper::class, function (MockInterface $mock){
      $mock->shouldReceive('post')
      ->andReturn(response()->json([$responseData], 200));
   })
);

and following everything I tried is the call to test my controller's function:

//Successfully add contacts to list
$this->json('POST', $addContactUri, $input_data, $token);
$this->seeStatusCode(201);

Now! Whatever I tried, it's as if the GuzzleWrapper is never mocked, it still does the post and doesn't return status code 200. No matter what I find on google, it never fits with this scenario... Can anyone help me?

0 likes
3 replies
automica's avatar

Can you edit your post and use three back ticks before and after each code block to format it?

automica's avatar

@dreamyt if you use Http facade,

   $response = Http::post($uri, $data);
   if($response->getStatusCode() != 200) { 
      return response()->json("Problem getting data", 500);
   }

then you should be able to use Http::fake

Http::fake(
   [$uri => Http::response([$responseData], 200)
);

see https://laravel.com/docs/8.x/http-client#testing

1 like

Please or to participate in this conversation.