I attempted to mock the StripeClient class in Laravel using Mockery and the app() helper. While I managed to mock the balance->retrieve method and simulate responses successfully, I encountered issues when trying to mock the constructor.
When using the app() helper to initiate StripeClient with constructor parameters, the constructor wasn't being mocked as expected.
Instead, the actual constructor was being called, leading to invalid key errors due to missing secrets. My aim was to control the Stripe API calls in unit tests, but I'm struggling to mock the constructor parameters and ensuring the desired behavior.
This is how I am initiating StripeClient in the Stripe service:
$this->stripeClient = app(StripeClient::class, [
'config' => $this->stripeSecretKey,
]);
I want to retrieve the balance:
$balance = $this->stripeClient
->balance
->retrieve(
[],
['stripe_account' => $stripeAccountId]
)
->toArray();
After some research, I found that Stripe calls request method behind the scenes when I call ->balance->retrieve.
So I tried to mock this as below in the test case:
$this->instance(
StripeClient::class,
\Mockery::mock(
StripeClient::class,
function (MockInterface $mock): void {
$mock->shouldReceive('request')
->zeroOrMoreTimes()
->andReturn([
'available' => [
'amount' => 1000,
],
'livemode' => false,
]);
}
)
);
This works when I call ->balance->retrieve by initiating the StripeClient as below (i.e. without passing the config param):
$stripeClient = app(StripeClient::class);
But when I pass a config param, it calls the original __construct method of StripeClient and throws the invalid key error:
$stripeClient = app(StripeClient::class, [
'config' => 'key',
]);
So I tried to mock the __construct as well like below but it seems it is not working. It's still calling the original constructor:
$mock->shouldReceive('__construct')
->with([
'config' => 'key',
])
->zeroOrMoreTimes()
->andReturnSelf();