통합을위한 조롱 및 스터브
1) 왜 미지와 플러그가 필요합니까?
결제 제공 업체, KYC 서비스, 메시지 브로커, CRM 등과의 통합으로 테스트가 느리고 불안정하며 비용이 많이 듭니다. 모키/플러그는 다음을 허용합니다
불안정한 환경에서 분리 서비스 로직
Determine 응답 및 오류
드문 경계 사례 재현 (타임 아웃, 429/5xx, 불일치);
로컬 및 CI에서 신속하고 예측 가능한 테스트를 실행하십시오.
2) 용어 및 분류
스터브는 상호 작용 검사없이 고정 된 응답이있는 간단한 스터브입니다.
Mock-통화를 기다리고 검증하는 객체 (주문/번호/인수).
Fake는 실제 동작이있는 단순화 된 구현 (예: In-Memory 저장소) 입니다.
스파이는 실제 통화를 기록하는 포장지입니다.
서비스 가상화는 스크립트, 상태 및 네트워크 기능이있는 "가상" 외부 서비스입니다.
기록/재생-실제 트래픽 및 후속 재생 기록 (필터/에디션 포함).
3) 테스트 안정성을위한 건축 패턴
Ports & Adapters (Hexagonal): 인터페이스를 넘어 통합을 수행하십시오. 가짜/모의로 쉽게 교체 할 수 있습니다.
부패 방지 계층 (ACL): 하나의 모듈이 외부 모델을 도메인 모델로 변환합니다.
계약 인식 클라이언트: OpenAPI/Protoguy 생성 → 더 적은 수동 불일치.
기능 플래그 및 샌드 박스 모드: 공급자의 안정을위한 보안 키/엔드 포인트.
4) HTT: 도구 및 예
4. 1 WireMock (독립형/자바 DSL)
JSON 찌르기: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 호버 플라이 (미들웨어, 레코드/재생)
공급자의 샌드 박스에 대한 트래픽을 기록하고 PII를 지우고 고정물로 수정하십시오.
시뮬레이션 모드에서는 200/4xx/5xx, 지연 및 "벗겨진" 창 변형을 추가하십시오.
4. 4 노드 (녹 )/파이썬 (응답 )/이동 ('
녹: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 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/프로토 타입
5. 1 스탭 생성
'.proto' 로 서버를 생성하고 제어 된 응답으로 메소드를 구현하십시오.
메타 데이터 (헤더), 상태 ('코드. InvalidArgument ',' 코드. 데드 라인 익스프레스 ').
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 grpcull
grpcurl -plaintext -d '{"amount":0}' localhost:50051 payouts. Payouts/Create
6) 게시물 및 스트림: Kafka/RabbitMQ
6. 1 스키마 인식 모키
테스트에서 Schema Registry를 사용하고 Avro/JSON-Schema/Protocu를 확인하십시오.
프로듀서 테스트: 메시지는 스키마에 해당합니다. 소비자 테스트: 기존 버전과 새 버전을 허용합니다.
6. 2 개의 테스트 컨테이너 (Kafka + 레지스트리 예)
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) 계약 인식 플러그
7. 1 협정 (CDC 조롱)
소비자는 기대치를 생성합니다 → 협정 파일 → 제공자가 스탠드에서 확인합니다.
Pact stub 서버는 클라이언트 통합 테스트에 대한 기대치를 재생합니다.
7. 2 OpenAPI/프로토 타입 → 안정적인 생성
사양에서 모의 서버를 올리는 도구 (프리즘, openapi-mock, grpc-mock 포함).
사양에 부정적인 예/코드를 포함합니다. 계약이기도합니다.
8) 네트워크와 혼돈: 실패 시뮬레이션
지연 및 지터: 고정/분산; 마감일 및 시도 당 타임 아웃을 확인하십시오.
타임 아웃/브레이크: 하프 오픈 연결, RST, 리셋 스트림 H2, 503/리셉션-애프터.
패킷 손실/중복: gRPC/스트림 용.
도구: Toxiprocy, MockServer (결함 주입), xk6- 파괴자, CI의 netem.
toxiproxy-cli toxic add psp --type latency --latency 300 --jitter 100
9) 데이터, 비밀 및 결정론
적색 및 합성: 수정에서 PII 없음; 돈-십진수/엄격한 형식.
시간 고정: 가짜 시계; "어제/오늘" -통제.
Idempotency: 동일한 'Idempotency-Key' → 동일한 응답.
발전기: 투명한 값을 가진 데이터의 공장/빌더 (예: 'test _ user _ 001').
버전 수정 (태그) 은 중재없이 "제거 된" 답변을 저장하지 않습니다.
10) CI/CD 및 환경
매트릭스: 단위 (공정 가짜) → 구성 요소 (로컬 가상화) → 통합 (최소 목, 테스트 컨테이너).
아티팩트: 압축 파일, OpenAPI 스냅 샷, ioc 서버 로그, 방울 용 PCAP.
병렬 처리: 고유 한 포트/키 접두사; 용기의 단열.
게이트: 계약 녹색 (CDC 확인), 사양 유효성 (보풀이), 네거티브가 통과되었습니다.
11) 안티 패턴
실제 서비스의 모키 "복사" 결함 → 잘못된 신뢰. 계약 및 정기적 인 기록/확인으로 처리됩니다.
모든 테스트에서 전 세계의 "거대" → 취약성, 값 비싼 주류. 얇은 포트와 ACL을 만드십시오.
실제 통합이 필요한 E2E의 Moki (특히 HMAC/mTLS를 사용한 결제/웹 후크).
시간/랜덤/네트워크 레이싱으로 인한 플레이크 → 결정 론적 좌석 인 가짜 시계를 사용합니다.
수정/저장소의 비밀. 비밀-비밀 저장 CI를 통해서만.
12) iGaming/Finance의 세부 사항
지불/인출: Mokes는 'Idempotency-Key', 'Redu-After', HMAC/mSL, 제재 코드 및 'long' 응답을 지원해야합니다.
보너스 논리/사기 방지: 속도/429 시나리오, ATO/챌린지, 위험 솔루션 '허용/거부/챌린지' TTL.
KYC/AML: KYC 레벨, 네거티브 (불일치, 유효하지 않은 문서), 재생 방지 웹 후크 ('X-Timestamp' 창) 별 샌드 박스 응답.
Jurisdictions/Tenants: 필요한 'X-Tenant/X-Region' 제목, 다른 응답 프로파일.
13) 미니 레시피 (치트 시트)
결제 반복: WireMock "Scenarios" - 첫 번째 '201', 두 번째 '409 복제'.
느린 PSP: MockServer '응답 지연' + 클라이언트에서 시도 당 시간 초과 확인.
웹 후크: 로컬 TP 서버 + HMAC 서명 확인; 5 초 후에 재생하면 두 배가되지 않습니다.
카프카 복제: 동일한 메시지를 두 번 게시; 핸들러는 demmpotent이어야합니다.
gRPC 상태: '코드' 테스트 행렬 (InvalidArgument, DeadlineExdrove, ResourceExhausted).
14) Prod 준비 점검표
- 포트/어댑터가 강조 표시됩니다. 통합은 인터페이스 뒤에 숨겨져 있습니다.
- TP/gRPC의 경우-네거티브가있는 계약 인식 스택 (Pact/OpenAPI/Proto) 이 있습니다.
- 중개인의 경우-테스트 컨테이너 + 레지스트리; 중복/주문/큰 메시지 테스트.
- 혼돈: 지연, 타임 아웃, 재설정, 429/503 ('재생 후'); 네트워크가 에뮬레이트됩니다 (Toxiproxy/netem).
- PII가없는 비품; 가짜 시계; demempotency가 발행되었습니다.
- CI 행렬: 단위 → 성분 → 통합; 로그/계약 아티팩트가 보존됩니다.
- 공급자 샌드 박스: 키가 분리되고 엔드 포인트가 구성되며 런북이 있습니다.
- 일정에 따라 기록/재생이 업데이트되고 추적이 편집됩니다.
- 화려한 지표 및 제어중인 테스트 기간; 성장시 경고.
15) TL; DR
얇은 포트를 통한 통합을 분리하고 작업에 적합한 도구를 사용하십시오: 간단한 경우를위한 스터브, 상호 작용 검증을위한 조롱, 실제 동작을위한 가짜, 네트워크를위한 서비스 가상화 및 혼돈 및 드문 오류. 모키 계약을 의식하고 (Pact/OpenAPI/Proto) 수정을 결정 론적이고 PII가없는 상태로 유지하고 지연/타임 아웃/429/5xx를 시뮬레이션하십시오. CI에서 피라미드 구축: 단위 → 구성 요소 → 통합; 빨간색 계약이있는 릴리스 블록. 결제/CCM 경로의 경우 HMAC/mTLS, demempotence 및 부정적인 시나리오를 고려하십시오.