Why not quickly rewrite it to use the laravel http client. It has mocking built in
Dec 11, 2021
4
Level 2
PHPUnit: Mock API Call using curl
The code snippet below is an API invocation to get an Access token from my local mobile provider's payment gateway. I've written unit test and it's passing but the problem is it's invoking the live API. How do I mock the API call?
Code under Test:
<?php
namespace Daraja\SDK;
final class Mpesa{
public static function getAccessToken($consumer_key,$consumer_secret)
{
$credentials = base64_encode($consumer_key.':'.$consumer_secret);
$ch = curl_init('https://sandbox.safaricom.co.ke/oauth/v1/generate?grant_type=client_credentials');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Basic '.$credentials,'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$curl_response = curl_exec($ch);
curl_close($ch);
$response=json_decode($curl_response,true);
return $response;
}
}
?>
The Test Class:
<?php
namespace Daraja\SDK;
use PHPUnit\Framework\TestCase;
use phpmock\phpunit\PHPMock;
use phpmock\MockBuilder;
final class MpesaTest extends TestCase
{
use PHPMock;
public function testAccessTokenCanBeGenerated()
{
$consumer_key='YOUR_CONSUMER_KEY';
$consumer_secret='YOUR_CONSUMER_SECRET';
$access_token=Mpesa::getAccessToken($consumer_key,$consumer_secret);
$this->assertIsArray($access_token,'is an array');
$this->assertNotEmpty($access_token,'array is not empty');
$this->assertEquals(2,count($access_token),'array has 2 items');
$this->assertArrayHasKey("access_token", $access_token,'array has key access_token');
$this->assertArrayHasKey("expires_in", $access_token,'array has key expires_in');
$this->assertNotEmpty($access_token['access_token'],'token is not empty');
}
}
I tried this(Mocking curl request):
<?php
$access_token=[
'access_token'=>'bY5yxSleFzHRkw9B6A7RfmV5SweK',
'expires_in'=>'3599'
];
$curl_exec = $this->getFunctionMock(__NAMESPACE__, "curl_exec");
$curl_exec->expects($this->once())->willReturn($access_token);
$ch = curl_init();
And also:
<?php
$builder = new MockBuilder();
$builder->setNamespace(__NAMESPACE__)
->setName("getAccessToken")
->setFunction(
function () {
return $access_token;
}
);
$mock = $builder->build();
But they didn't work. The mock build passes the test but when I remove the code under test the test still passes.
Any help will be highly appreciated.
Please or to participate in this conversation.