You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel-Stripe-PHP测试:Mock StripeClient及方法实现测试覆盖

Mock Stripe Client 实现测试覆盖的方案

1. 先重构代码:用依赖注入替代直接实例化

要Mock StripeClient,首先得避免在业务代码里直接new StripeClient()——这种硬编码实例化的方式会让Mock变得困难。改成通过构造函数注入StripeClient,让测试时能轻松替换成Mock实例。

原代码(难Mock):

class PaymentService {
    public function createPaymentIntent(array $params) {
        $stripe = new StripeClient('sk_test_xxx');
        return $stripe->paymentIntents->create($params);
    }
}

重构后代码(易Mock):

class PaymentService {
    private $stripeClient;

    // 构造函数注入StripeClient实例
    public function __construct(\Stripe\StripeClient $stripeClient) {
        $this->stripeClient = $stripeClient;
    }

    public function createPaymentIntent(array $params) {
        return $this->stripeClient->paymentIntents->create($params);
    }
}

2. 用PHPUnit Mock StripeClient及PaymentIntents

Stripe SDK是链式调用(stripe->paymentIntents->create()),所以需要Mock两层:StripeClient本身,以及它返回的PaymentIntentService实例。

测试示例代码

use PHPUnit\Framework\TestCase;
use Stripe\StripeClient;
use Stripe\Service\PaymentIntentService;
use Stripe\PaymentIntent;

class PaymentServiceTest extends TestCase {
    public function testCreatePaymentIntent() {
        // 1. Mock PaymentIntentService,预设create方法的返回值
        $mockPaymentIntent = $this->createMock(PaymentIntent::class);
        $mockPaymentIntent->method('__get')->with('id')->willReturn('pi_123456');

        $mockPaymentIntentService = $this->createMock(PaymentIntentService::class);
        $mockPaymentIntentService->expects($this->once())
            ->method('create')
            ->with([
                'amount' => 1000,
                'currency' => 'usd',
                'payment_method_types' => ['card']
            ])
            ->willReturn($mockPaymentIntent);

        // 2. Mock StripeClient,让它返回上面Mock的PaymentIntentService
        $mockStripeClient = $this->createMock(StripeClient::class);
        $mockStripeClient->method('__get')
            ->with('paymentIntents')
            ->willReturn($mockPaymentIntentService);

        // 3. 注入Mock实例,执行测试方法
        $paymentService = new PaymentService($mockStripeClient);
        $result = $paymentService->createPaymentIntent([
            'amount' => 1000,
            'currency' => 'usd',
            'payment_method_types' => ['card']
        ]);

        // 4. 断言结果符合预期
        $this->assertEquals('pi_123456', $result->id);
    }
}

3. 链式调用Mock的注意点

  • StripeClient通过魔术方法__get返回各类服务(比如paymentIntents对应PaymentIntentService),所以Mock时要针对__get方法,传入服务名称并返回Mock的服务实例。
  • 可以通过expects($this->once())验证目标方法是否被调用,with()匹配传入的参数,确保业务逻辑传参正确。

4. 验证测试覆盖

用PHPUnit生成代码覆盖率报告,确认业务代码是否被完全覆盖:

phpunit --coverage-html coverage-report

打开生成的coverage-report/index.html,就能查看PaymentService中每一行代码的覆盖情况。

框架适配(以Laravel为例)

如果用Laravel这类依赖注入框架,可以在测试的setUp方法中绑定Mock实例到容器:

protected function setUp(): void {
    parent::setUp();
    
    $mockPaymentIntentService = $this->createMock(PaymentIntentService::class);
    // 配置Mock逻辑...
    
    $mockStripeClient = $this->createMock(StripeClient::class);
    $mockStripeClient->method('__get')->with('paymentIntents')->willReturn($mockPaymentIntentService);
    
    $this->app->bind(StripeClient::class, fn() => $mockStripeClient);
}

这样测试时框架会自动注入Mock实例,无需手动传入。

内容的提问来源于stack exchange,提问作者tcgkn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 14:02:33