Back to Course |
Testing in Laravel 11: Advanced Level

Testing Third-Parties with Sandbox Mode

Now, let's cover the case where you DO want to test the external service and make the request to that service without faking it.

For this, we will check the example from the open-source package Laravel Cashier.


In the main FeatureTestCase.php file, we have the stripe() method, which creates the Cashier Stripe object with a real API key of Stripe.

use Laravel\Cashier\Cashier;
use Laravel\Cashier\Tests\TestCase;
use Stripe\StripeClient;
 
abstract class FeatureTestCase extends TestCase
{
// ...
 
protected static function stripe(array $options = []): StripeClient
{
return Cashier::stripe(array_merge(['api_key' => getenv('STRIPE_SECRET')], $options));
}
 
// ...
}

Important point: Your Stripe API Key should be from your testing Stripe environment. In your provider's external API, it may be called a Sandbox or a Developer Account, or you could even create a totally separate account just for testing purposes.

Then, you set those API keys in the automated test itself, globally in the .env file of your testing environment on the server or wherever you emulate that test, like GitHub actions.

Then, the package Cashier Stripe executes all the Stripe requests but with your testing account.

Then, for the test itself, let's take a look at an example from CheckoutTest:

use Laravel\Cashier\Checkout;
 
class CheckoutTest extends FeatureTestCase
{
// ...
 
public function test_customers_can_start_a_product_checkout_session()
{
$user = $this->createCustomer('customers_can_start_a_product_checkout_session');
 
$shirtPrice = self::stripe()->prices->create([
'currency' => 'USD',
'product_data' => [
'name' => 'T-shirt',
],
'unit_amount' => 1500,
]);
 
$carPrice = self::stripe()->prices->create([
'currency' => 'USD',
'product_data' => [
'name' => 'Car',
],
'unit_amount' => 30000,
]);
 
$items = [$shirtPrice->id => 5, $carPrice->id];
 
$checkout = $user->checkout($items, [
'success_url' => 'http://example.com',
'cancel_url' => 'http://example.com',
]);
 
$this->assertInstanceOf(Checkout::class, $checkout);
}
 
// ...
}

What is happening here?

  • self::stripe() is called multiple times
  • With that testing-environment object, we create the prices twice
  • With the same object, we perform the checkout.

In other words, you need to set up such tests in a way that you set up your testing sandbox credentials once in some global config, constructor method, or similar.

Then, your actual code would just use the real API production keys, and the testing suite would replace them with sandbox/testing credentials.