Golang测试中模拟Stripe调用的方法

Golang测试中模拟Stripe调用的方法 我正在编写测试,需要模拟Stripe调用,但无法实现模拟。求助! 谢谢

6 回复

你能发送你的代码和捕获的错误吗?

更多关于Golang测试中模拟Stripe调用的方法的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


你所说的“条带调用”是什么意思?

当我想获取Stripe客户、收费、发票或其他内容时

是的,关于那个 Stripe

我想模拟从 Stripe 收到的 webhook。 我使用的是 github.com/stretchr/testify/mock

type mockClient struct {
	client.API
	mock.Mock
}

并且我重写了我要使用的方法。

我遇到了一个错误,提示我无法将 mockClient 用作 client.API

那么你指的是 https://stripe.com/,对吗?

请帮助我们更好地帮助你。

  • 你想模拟什么:一个 REST API?具体是哪个?
  • 你使用任何模拟库吗?是哪个?你是怎么使用的?
  • 你写过任何代码吗?请展示相关的部分。
  • 你遇到任何错误了吗?具体是什么?
  • 你期望得到什么结果?实际得到的结果又是什么?

在Golang测试中模拟Stripe调用,可以使用接口和依赖注入。以下是具体实现:

1. 定义支付接口

package payment

import (
    "github.com/stripe/stripe-go/v78"
)

type StripeClient interface {
    CreateCharge(amount int64, currency, customerID string) (*stripe.Charge, error)
    CreateCustomer(email string) (*stripe.Customer, error)
    RefundCharge(chargeID string) (*stripe.Refund, error)
}

type RealStripeClient struct {
    APIKey string
}

func (c *RealStripeClient) CreateCharge(amount int64, currency, customerID string) (*stripe.Charge, error) {
    // 实际Stripe API调用
    params := &stripe.ChargeParams{
        Amount:   stripe.Int64(amount),
        Currency: stripe.String(currency),
        Customer: stripe.String(customerID),
    }
    return charge.New(params)
}

func (c *RealStripeClient) CreateCustomer(email string) (*stripe.Customer, error) {
    params := &stripe.CustomerParams{
        Email: stripe.String(email),
    }
    return customer.New(params)
}

2. 创建模拟客户端

package payment

import (
    "errors"
    "github.com/stripe/stripe-go/v78"
)

type MockStripeClient struct {
    Charges   map[string]*stripe.Charge
    Customers map[string]*stripe.Customer
    ShouldFail bool
}

func NewMockStripeClient() *MockStripeClient {
    return &MockStripeClient{
        Charges:   make(map[string]*stripe.Charge),
        Customers: make(map[string]*stripe.Customer),
    }
}

func (m *MockStripeClient) CreateCharge(amount int64, currency, customerID string) (*stripe.Charge, error) {
    if m.ShouldFail {
        return nil, errors.New("mock API failure")
    }
    
    charge := &stripe.Charge{
        ID:       "ch_mock_" + customerID,
        Amount:   amount,
        Currency: currency,
        Customer: &stripe.Customer{ID: customerID},
        Status:   stripe.ChargeStatusSucceeded,
    }
    
    m.Charges[charge.ID] = charge
    return charge, nil
}

func (m *MockStripeClient) CreateCustomer(email string) (*stripe.Customer, error) {
    if m.ShouldFail {
        return nil, errors.New("mock API failure")
    }
    
    customer := &stripe.Customer{
        ID:    "cus_mock_" + email,
        Email: email,
    }
    
    m.Customers[customer.ID] = customer
    return customer, nil
}

3. 业务逻辑使用接口

package payment

type PaymentProcessor struct {
    Client StripeClient
}

func NewPaymentProcessor(client StripeClient) *PaymentProcessor {
    return &PaymentProcessor{Client: client}
}

func (p *PaymentProcessor) ProcessPayment(amount int64, currency, customerID string) (string, error) {
    charge, err := p.Client.CreateCharge(amount, currency, customerID)
    if err != nil {
        return "", err
    }
    return charge.ID, nil
}

4. 测试用例

package payment_test

import (
    "testing"
    "yourproject/payment"
    "github.com/stretchr/testify/assert"
)

func TestPaymentProcessor_ProcessPayment(t *testing.T) {
    mockClient := payment.NewMockStripeClient()
    processor := payment.NewPaymentProcessor(mockClient)
    
    chargeID, err := processor.ProcessPayment(1000, "usd", "cus_123")
    
    assert.NoError(t, err)
    assert.Contains(t, chargeID, "ch_mock_cus_123")
    assert.Len(t, mockClient.Charges, 1)
}

func TestPaymentProcessor_ProcessPayment_Failure(t *testing.T) {
    mockClient := payment.NewMockStripeClient()
    mockClient.ShouldFail = true
    processor := payment.NewPaymentProcessor(mockClient)
    
    chargeID, err := processor.ProcessPayment(1000, "usd", "cus_123")
    
    assert.Error(t, err)
    assert.Equal(t, "", chargeID)
}

func TestPaymentProcessor_Integration(t *testing.T) {
    if testing.Short() {
        t.Skip("跳过集成测试")
    }
    
    realClient := &payment.RealStripeClient{
        APIKey: "sk_test_...",
    }
    processor := payment.NewPaymentProcessor(realClient)
    
    customer, _ := realClient.CreateCustomer("test@example.com")
    chargeID, err := processor.ProcessPayment(1000, "usd", customer.ID)
    
    assert.NoError(t, err)
    assert.NotEmpty(t, chargeID)
}

5. 使用gomock生成模拟

# 安装mockgen
go install github.com/golang/mock/mockgen@v1.6.0

# 生成mock
mockgen -source=payment.go -destination=mock_payment/mock_stripe.go -package=mock_payment

这种方法通过接口抽象Stripe依赖,使测试不依赖外部API,同时保持生产代码的完整性。

回到顶部