GH GambleHub

用於集成的Mocking和stubs

1)為什麼需要清洗和存根

與支付提供商,KYC服務,消息經紀人,CRM等的集成使測試緩慢,不穩定且昂貴。清洗/存根允許:
  • 將服務邏輯與不穩定的環境隔離開來;
  • 確定答案和錯誤;
  • 重現罕見的邊界案例(taymauts,429/5xx,非約束性);
  • 在本地和CI中快速、可預測地運行測試。
💡 原理:測試級別(單位/組件)越低,替換越多;越接近原生現實(Integration/E2E),插頭越少。

2)術語和分類法

Stub是一個簡單的固定響應存根,沒有交互檢查。
Mock是等待呼叫並對其進行驗證的對象(順序/數量/參數)。
Fake是具有真實行為的簡化實現(例如In-Memory存儲庫)。
Spy是記錄實際呼叫的包裝紙。
服務虛擬化是一種具有腳本,狀態和網絡功能的「虛擬」外部服務。
Record/Replay-記錄真實流量並隨後播放(帶過濾器/編輯)。

什麼時候選擇:
三.情況工具
純粹的商業邏輯Fakes (in-memory), unit-mocks
與簡單案例的HTTP集成Stubs (WireMock/MockServer/HTTPServer)
驗證客戶與提供商的合同CDC mocks (Pact)
復雜的腳本/狀態/網絡錯誤Service virtualization / Hoverfly / MockServer
消息(Kafka/RabbitMQ)Testcontainers+schema-aware生產商/消費者stubs

3)可測試性的建築模式

端口和適配器(Hexagonal):提供接口集成-易於替換為fake/mock。
反腐敗層(ACL):一個模塊將外部模型轉換為域-少於mok點。
客戶端:通過OpenAPI/Protobuf生成→減少手動不匹配。
功能標誌和sandbox模式:提供商穩定性的安全密鑰/端點。

4)HTTP: 工具和示例

4.1 WireMock (standalone/Java DSL)

JSON-I:
json
{
"request": { "method": "POST", "urlPath": "/v1/payouts", "headers": { "Idempotency-Key": { "matches": ".+" } } },
"response": {
"status": 201,
"headers": { "Content-Type": "application/json" },
"jsonBody": { "id": "po_123", "status": "queued" },
"fixedDelayMilliseconds": 80
}
}
Java DSL(具有身體檢查和變化):
java stubFor(post(urlEqualTo("/v1/payouts"))
.withHeader("Idempotency-Key", matching(".+"))
.withRequestBody(matchingJsonPath("$.amount", equalTo("100. 00")))
.willReturn(aResponse(). withStatus(201). withHeader("Content-Type","application/json")
.withBody("{\"id\":\"po_123\",\"status\":\"queued\"}")));

4.2 MockServer(揚聲器/驗證)

json
{
"httpRequest": { "method": "GET", "path": "/v1/wallets/w123" },
"httpResponse": { "statusCode": 200, "headers":[{"name":"Content-Type","values":["application/json"]}],
"body": { "id":"w123","currency":"EUR","balance":0 } }
}

4.3 Hoverfly (middleware, record/replay)

記錄與提供商「沙箱」的流量,清除PII,記錄為固定。
在模擬模式下,添加變體:200/4xx/5xx、延遲和「flaky」窗口。

4.4 Node (Nock) / Python (responses) / Go (`httptest`)

Nock:

js nock('https://psp. example. com')
.post('/v1/payouts'). reply(201, { id:'po_123', status:'queued' })
.post('/v1/payouts'). reply (409, {code: 'duplicate'}) ;//second call - conflict

Go:

go srv:= httptest. NewServer(http. HandlerFunc(func(w http. ResponseWriter, r http. Request){
if r. Header. Get("Idempotency-Key") == "" { w. WriteHeader(400); return }
w. Header(). Set("Content-Type","application/json")
w. WriteHeader(201); w. Write([]byte(`{"id":"po_123","status":"queued"}`))
}))
defer srv. Close()

5) gRPC/Protobuf

5.1 Staba生成

通過「.proto」生成服務器,實現受控響應的方法。

檢查元數據(headers)、狀態('codes.InvalidArgument`, `codes.DeadlineExceeded`).

Go gRPC fake(片段):
go type FakePayouts struct{ pb. UnimplementedPayoutsServer }
func (f FakePayouts) Create(ctx context. Context, in pb. PayoutReq)(pb. PayoutRes,error){
if in. Amount <= 0 { return nil, status. Error(codes. InvalidArgument,"amount>0") }
return &pb. PayoutRes{Id:"po_123", Status:"QUEUED"}, nil
}

5.2 grpcurl用於底片


grpcurl -plaintext -d '{"amount":0}' localhost:50051 payouts. Payouts/Create

6)消息和流: Kafka/RabbitMQ

6.1 Schema-aware洗衣機

使用Schema Registry並在測試中驗證Avro/JSON-Schema/Protobuf。
生產者測試:消息符合模式;消費者測試:接受新舊版本。

6.2 Testcontainers(Kafka+Registry示例)

java
KafkaContainer kafka = new KafkaContainer(DockerImageName. parse("confluentinc/cp-kafka:7. 6. 1"));
kafka. start();
//We publish the event and wait for consumption with deduplication by key

6.3負片

復制,順序排列,延遲交付,「有毒」消息(死信)。
大消息(近極限),未知版本的電路。

7) Contract-aware存根

7.1 Pact (CDC mocks)

消費者形成期望→ pact文件→提供者在展位上驗證。
Pact stub Server播放客戶端集成測試的期望值。

7.2 OpenAPI/Protobuf → Stabes生成

使莫克服務器脫離規範的工具(例如:Prism,openapi-mock,grpc-mock)。
在規範中包含負面的示例/代碼:這也是合同。

8)網絡與混亂: 故障模擬

延遲和擠壓:固定/分布;檢查截止日期和工作時間。
Taymauts/斷裂:半開放連接,RST,H2流重置,503/Retry-After。
批量丟失/重復:適用於gRPC/流。
工具:Toxiproxy, MockServer (fault injection), xk6-disruptor, netem in CI。

Toxiproxy(CLI)示例:

toxiproxy-cli toxic add psp --type latency --latency 300 --jitter 100

9)數據、秘密和決定論

Redact和合成劑:虛構中沒有PII;金錢-decimal/嚴格的格式。
時間固定:假時鐘;「昨天/今天」-控制。
相同性:相同的「Idempotency-Key」 →相同的答案。

生成器: 具有透明值(e.g., `test_user_001`).

轉化虛擬文件(標簽),不要在沒有中介的情況下存儲「刪除」的答案。

10)CI/CD和環境

矩陣:單位(流程錯誤)→組件(本地虛擬化)→整合(最低限度moks,Testcontainers)。
工件:pact文件、OpenAPI snapshots、moc服務器日誌、PCAP。
並發:唯一的端口/密鑰前綴;容器隔離。
門:合同綠色(CDC驗證),規範驗證值(lint),底片通過。

11)反模式

Moks「復制」了實際服務的缺陷→虛假的信心。接受合同和定期記錄/驗證的治療。
整個世界的「Macromoki」在每次測試中都→脆弱性,昂貴的主流。完成薄端口和ACL。
洗滌到需要真正集成的E2E(尤其是使用HMAC/mTLS 的支付/webhooks)。
由於時間/隨機/網絡比賽而產生的長笛→使用假時鐘,確定性座位。
虛構/存儲庫中的秘密。秘密-僅通過CI秘密存儲。

12) iGaming/財務細節

付款/結論:洗滌應支持「Idempotency-Key」,「Retry-After」,HMAC/mTLS,制裁代碼和「長期」響應。
Bonus Logic/antifrod:velocity/429腳本,ATO/挑戰,TTL的「allow/deny/challenge」風險解決方案。
KYC/AML:對KYC級別,否定詞(mismatch,無效文檔),帶有反重播的webhooks(「X-Timestamp」窗口)的sandbox響應。
司法管轄區/特南特:強制性標題「X-Tenant/X-Region」,不同的響應配置文件。

13)迷你食譜(spargalka)

重復付款:WireMock 「Scenarios」是第一個「201」,第二個是「409 duplicate」。
慢速PSP: MockServer的「響應延遲」+檢查客戶端中的工作時間。
Webhooks:本地HTTP服務器+HMAC簽名驗證;5秒後的重播不會產生雙打。
Kafka副本:兩次發布同一消息;亨德勒必須保持相等。
gRPC狀態:通過「代碼」進行矩陣測試(InvalidArgument,DeadlineExceeded,ResourceExhausted)。

14)準備就緒支票清單

  • 分配端口/適配器;集成隱藏在接口後面。
  • 對於HTTP/gRPC-存在帶有底片的contract-aware stables (Pact/OpenAPI/Proto)。
  • 對於經紀人-Testcontainers+Registry;重復/順序/大消息測試。
  • 混亂:延誤、停頓、重置,429/503 with 「Retry-After」;網絡被模擬(Toxiproxy/netem)。
  • 沒有PII的Fixtura;fake clock;偶然性。
  • CI矩陣:單位→組件→整合;文物/合同保存。
  • 提供商的沙箱:密鑰是分離的,後端是配置的,有運行簿。
  • Record/Replay會按計劃更新,信托會編輯。
  • 控制下測試的flaky和持續時間的度量;生長時的異常。

15) TL;DR

通過薄端口隔離集成,並使用正確的工具執行任務:用於簡單案例的堆棧、用於驗證交互的堆棧、用於現實行為的堆棧、用於網絡和罕見錯誤的服務虛擬化和chaos。使洗滌合約(Pact/OpenAPI/Proto),保持假象確定性和沒有PII, 模擬延遲/taymauts/429/5xx。在CI中構建金字塔:單位→組件→集成;以紅色合同阻止發布。對於支付/KUS路徑,請考慮HMAC/mTLS,等效性和負面情況。

Contact

與我們聯繫

如有任何問題或支援需求,歡迎隨時聯絡我們。我們隨時樂意提供協助!

開始整合

Email 為 必填。Telegram 或 WhatsApp 為 選填

您的姓名 選填
Email 選填
主旨 選填
訊息內容 選填
Telegram 選填
@
若您填寫 Telegram,我們將在 Email 之外,同步於 Telegram 回覆您。
WhatsApp 選填
格式:國碼 + 電話號碼(例如:+886XXXXXXXXX)。

按下此按鈕即表示您同意我們處理您的資料。