Mokking e stubs per le integrazioni
1) A cosa servono moki e stub
Integrazioni con provider di pagamenti, servizi KYC, broker di messaggi, CRM, ecc. rendono i test lenti, instabili e costosi. Moki/stub consentono:- isolare la logica del servizio dall'ambiente instabile;
- Determinare le risposte e gli errori
- riproduce le valigette limite rare (timeout, 429/5xx, non-consolazione);
- eseguire i test in locale e in CI in modo rapido e prevedibile.
2) Termini e tassonomia
Stub è un semplice stub con una risposta fissa, senza controlli di interazione.
Mock è l'oggetto che attende e verifica le chiamate (ordine/numero/argomenti).
Fake - Implementazione semplificata (ad esempio In-Memory repository) con un comportamento reale.
Spy è un involucro che registra le chiamate effettive.
Servizio Virtualization è un servizio esterno «virtuale» con script, stato e caratteristiche di rete.
Record/Replay - Registrazione del traffico reale e riproduzione successiva (con filtri/redazione).
3) Pattern architettonici per la testabilità
Porte & Adatters (Arcagonal) - Porta l'integrazione oltre le interfacce - facilmente sostituibile con fake/mock.
Livello anticorruzione (ACL) - Un singolo modulo trasforma il modello esterno in un modello di dominio: meno punti Mook.
Client Contract-aware - Generare per meno discrepanze manuali.
Feature flag e modalità sandbox: chiavi/endpoint sicure per il provider stab.
4) HTTP: strumenti e esempi
4. 1 WireMock (standalone/Java DSL)
JSON-stab: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 (con controllo del corpo e variazioni):
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 (altoparlanti/verifiche)
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)
Registrare il traffico contro il fornitore di sabbia, pulire il PII e fissare come fissture.
In modalità simulata, aggiungete le variazioni: 200/4xx/5xx, ritardi e «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 Generazione di stub
Generare un server per «.proto», implementare metodi con risposte controllate.
Controllare i metadati (headers), gli stati ('codes. InvalidArgument`, `codes. DeadlineExceeded`).
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 per negativi
grpcurl -plaintext -d '{"amount":0}' localhost:50051 payouts. Payouts/Create
6) Messaggi e striam:
6. 1 Schema-aware moki
Utilizzare Schema Registry e convalidare Avro/JSON-Schema/Protobuf nei test.
Test producer: il messaggio corrisponde allo schema. Test consumer: accetta le versioni precedenti e nuove.
6. 2 Testcontainers (esempio 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 Negativi
Duplicati, riordino, consegna ritardata, messaggi «velenosi» (dead-letter).
Messaggi di grandi dimensioni (near-limit), versioni di diagrammi non riconosciute.
7) Contract-aware stub
7. 1 Pact (CDC mocks)
Il consumer crea le aspettative per il file pact provider viene convalidato sullo stand.
Il pub stub server riproduce le aspettative per i test di integrazione del client.
7. 2 generazione stub
Strumenti che sollevano il MCU dalla specifica (ad esempio Prism, openapi-mock, grpc-mock).
Includere esempi/codici negativi nella specifica, anche questo è un contratto.
8) Rete e caos: simulazione di guasti
Ritardi e jitter: fissi/distribuiti controllare i deadline e per-try timeout.
Timeout/interruzioni: connessioni half-open, RST, reset thread H2, 503/Retry-After.
Perdita/duplicati batch per gRPC/striam.
Strumenti: Toxiproxy, MockServer (fault injection), xk6-disruptor, netem in CI.
toxiproxy-cli toxic add psp --type latency --latency 300 --jitter 100
9) Dati, segreti e determinismo
Redact e sintetico: niente PII nelle ficsture; denaro - decimale/formattazione rigorosa.
Tempo fisso: fake clock; «ieri/oggi», controllate.
Idampotenza, la stessa identica'Idempotency-Key ', stessa risposta.
Generatori: fabbriche/cartelli dati con valori trasparenti (e. g., `test_user_001`).
Versionare le ficsture (tag), non memorizzare le risposte «rimosse» senza la mediazione.
10) CI/CD e ambiente
Matrice: unit (in-process fakes) → component (virtualizzazione locale) → integration (minimo moc, Testcontainers).
Gli artefatti sono i file pact, gli strumenti OpenAPI, i loghi dei server MCAP, i PCAP per le cadute.
Parallelità: porte/prefissi di chiave univoci Isolamento dei contenitori.
Gate: contratto verde (CDC verify), specifica valida (lint), negativi superati.
11) Antipattern
I moki «copiano» i difetti del servizio vero e proprio. Trattata con contratti e record/verify periodici.
I Macromocchi di tutto il mondo sono fragili in ogni test, costoso maintenance. Eseguire porte sottili e ACL.
Moki in E2E, dove è necessaria una vera integrazione (in particolare pagamenti/webhoop con HMAC/mTLS).
Flaconcini a causa di tempo/random/corse di rete, usate fake clock, sedili determinati.
I segreti in un repository/ficstour. I segreti sono solo attraverso il segreto-magazzino CI.
12) Specificità iGaming/finanza
Pagamenti/conclusioni: i moki devono supportare «Idempotency-Key», «Retry-After», i codici delle sanzioni e le risposte «lunghe».
Bonus-logica/antifrode: script velocity/429, AT/challenge, rischioso-soluzioni «allow/deny/challenge» con TTL.
KYC/AML: risposte sandbox per livello KYC, negativi (mismatch, documenti non validi), webhook con anti-replay ('X-Timestamp', finestra).
Giurisdizioni/tenanti: intestazioni obbligatorie «X-Tenant/X-Region», profili di risposta diversi.
13) Mini-ricette (scaffale)
Ripetizione del pagamento: «Scenarius», primo «201», secondo «409 duplicato».
PSP lento: MockServer 'responseDelay' + test per-try timeout nel client.
Webhooks: server HTTP locale + convalida firma HMAC; Una ripetizione dopo 5 secondi non crea una ripresa.
Kafka-duplicati - Pubblicare lo stesso messaggio due volte; Hendler deve essere idipotente.
States GRPC: matrix test per codes (InvalidArgument, DeadlineExceeded, ResourceExhausted).
14) Foglio di assegno prod
- Porte/adattatori selezionati Le integrazioni sono nascoste dietro le interfacce.
- Per il HTTP/gRPC - ci sono contract-aware di greggi (Pact/OpenAPI/Proto) con negativi.
- Per i broker - Testcontainers + Registry; test di duplicazione/ordine/messaggi di grandi dimensioni.
- Caos: ritardi, timeout, reset, 429/503 con'Retry-After '; la rete viene emulata (Toxiproxy/netem).
- Ficsture senza PII; fake clock; L'idipotenza va avanti.
- Matrice CI: unit → component → integration; gli artefatti dei reparti/contratti sono conservati.
- Cassette di sabbia provider: chiavi separate, endpoint configurati e runbook.
- Record/Replay viene aggiornato in base alla pianificazione e i tralicci vengono modificati.
- Metriche flaky e durata dei test sotto controllo; Gli alert sono alti.
15) TL; DR
Isolare le integrazioni attraverso porte sottili e utilizzare lo strumento giusto per: stubs per semplici valigette, mocks per verificare le interazioni, fakes per comportamenti realistici, servizio virtualization e chaos per errori di rete e rari. Rendete i moki un contratto consapevole (Pact/OpenAPI/Proto), mantenete i firewall determinati e senza PII, simulate ritardi/timeout/429/5xx. In CI, costruisci la piramide unit → component → integration; Il rilascio è bloccato con i contratti rossi. Per i percorsi di pagamento/CUS, tenere conto di HMAC/mTLS, idipotenza e scenari negativi.