Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

forrestedw's avatar

Stripe Error : Call to a member function setLastResponse() on array

I'm getting this error in unit tests. Everything runs fine in the browser:

Error : Call to a member function setLastResponse() on array
 /Users/.../vendor/stripe/stripe-php/lib/BaseStripeClient.php:137
 /Users/.../vendor/stripe/stripe-php/lib/Service/AbstractService.php:75
 /Users/.../vendor/stripe/stripe-php/lib/Service/PaymentIntentService.php:134
 /Users/.../app/Services/Stripe/Repositories/PaymentIntentRepository.php:57
 /Users/.../app/Http/Controllers/OrderController.php:43

I only get the error when I run my full test suite. If I run just the test method that the error gets throwing in, or even the class the method is in, everything is fine. What could be causing the error?

0 likes
8 replies
forrestedw's avatar

It's mocked. Here is the test:

/**
 * @testdox Handle payment_intent.succeeded
 */
public function testHandlePaymentIntentSucceeded(): void
{
    /** @var \App\Models\Basket $basket */
    $basket = Basket::factory()->create();

    $this->mock(CreateOrder::class, function (MockInterface $mock) use ($basket) {
        $mock
            ->shouldReceive('handle')
            ->once()
            ->withArgs(function (Basket $basketArg, PaymentIntent $paymentIntent) use ($basket) {
                return $basketArg->is($basket) && $paymentIntent->id === 'pi_test';
            });
    });

    $this->mock(StripeClient::class);

    $this->sendWebhook([
        'type' => 'payment_intent.succeeded',
        'data' => [
            'object' => [
                'charges' => [
                    'object' => 'list',
                    'data' => [
                        [
                            'id' => 'ch_test',
                            'metadata' => [
                                'basket_id' => (string) $basket->getKey(),
                            ],
                            'object' => 'charge',
                            'status' => 'succeeded',
                        ],
                    ],
                ],
                'id' => 'pi_test',
                'object' => 'payment_intent',
            ],
        ],
    ])->assertSuccessful();
}

protected function sendWebhook(array $data = []): TestResponse
{
    return $this->withoutExceptionHandling()->postJson('/stripe/webhook', $data);
}
automica's avatar

what is going on at Controllers/OrderController.php:43 ?

forrestedw's avatar

@automica

This:

// lines 42 to 44 of OrderController.php
        return view('orders.create', [
            'paymentIntent' => $paymentIntents->createFromBasket($basket),
        ]);

Which leads to this:

public function createFromBasket(Basket $basket): PaymentIntent
{
    $basket->loadMissing('basketItems.product');

    $basketAmount = $basket->total();

    $params = [
        'amount' => $basketAmount,
        'currency' => 'gbp',
        // todo rename basket in Stripe to something more descriptive
        'description' => sprintf('Basket %s', $basket->getKey()),
        'metadata' => [
            'basket_id' => (string) $basket->getKey(),
        ],
        'payment_method_types' => ['card'],
    ];

    if (app()->environment() !== 'production') {
        $params['metadata']['integration_check'] = 'accept_a_payment';
    }

    return $this->stripe->paymentIntents->create($params);
}
automica's avatar

do you have any tests which hit that method that don't have the stripe bit mocked?

forrestedw's avatar

Ah yes I do. for example this one:

public function it_shows_product_in_checkout()
{
    $product = Product::factory()->create();

    $product->addToBasket(1);

    $this->get(route('order.create')) // $paymentIntents->createFromBasket($basket) called in here
        ->assertOk()
        ->assertViewIs('orders.create')
        ->assertSee($product->name)
        ->assertSee(Str::penceToPounds($product->price));
}

How would I mock the StripeClient here? I tired adding $this->mock(StripeClient::class) at the beginning of the method which throws this error:

Mockery\Exception\BadMethodCallException : Received Mockery_2_Stripe_StripeClient::request(), but no expectations were specified
automica's avatar
automica
Best Answer
Level 54

How would I mock the StripeClient here?

you shouldn't. You should mock PaymentIntents and define a response for 'createFromBasket'.

That should contain the response you are expecting from stripe.

1 like
forrestedw's avatar

@automica Thank you. It took me a moment to understand the principles of mocking but I do now. Solution was this, for those that it helps:

$paymentIntent = $this->mock(PaymentIntentRepository::class);

        $paymentIntent->shouldReceive('createFromBasket')
            ->once()
            ->withArgs(function($communityArg, $basketArg) {
                return $basketArg->is(basket()->refresh()) && $communityArg->is($this->community);
            })->andReturn($this->createPaymentIntent());
1 like

Please or to participate in this conversation.