Pact.io测试报错:Missing requests问题排查求助
核心问题分析
报错提示Missing requests: POST /api/objects/tt/record/,说明实际发送的请求与Pact预定义的交互不匹配,或请求未被正确捕获,以下是具体排查及修复点:
1. 请求Body不匹配
服务代码中linkObjectToPL方法发送的POST Body包含两个字段:
{ id: objectId, destRecordId: recordId // 调用时传入undefined }
但Pact预定义的交互里,预期Body仅包含{id: mockObjectId},无destRecordId字段。Pact默认严格匹配请求Body的所有字段,实际请求多了destRecordId: undefined时,会被判定为不匹配,导致请求未被识别。
修复方案:
- 方案一:在Pact的
withRequest中添加destRecordId的可选预期:
body: { id: mockObjectId, destRecordId: Matchers.optional(Matchers.nullOrUndefined()) }
- 方案二:在服务方法中仅当
recordId存在时才添加该字段:
const body: any = { id: objectId }; if (recordId) { body.destRecordId = recordId; } return this.httpClient.post(`objects/${encodeURIComponent(topicId)}/record/`, body)
2. 测试未等待异步请求完成
测试用例中调用dndService.linkObjectToPL().subscribe()后,未等待异步请求完成就结束了测试,此时Pact还未收到请求,就执行了afterEach中的provider.verify(),导致报缺失请求。
修复方案:
改用async/await配合RxJS的firstValueFrom等待请求完成:
// 先导入依赖 import { firstValueFrom } from 'rxjs'; it('returns the correct response', async () => { const dndService: DragNDropService = TestBed.inject(DragNDropService); const response = await firstValueFrom(dndService.linkObjectToPL(mockTopicId, mockObjectId)); expect(response).not.toBeNull(); });
3. 请求路径编码不一致
服务代码对topicId做了encodeURIComponent编码处理,但Pact预定义路径是直接拼接mockTopicId。若mockTopicId包含特殊字符,会导致实际请求路径与预期路径不匹配。
修复方案:
在Pact的路径中同样使用编码后的mockTopicId:
path: `/api/objects/${encodeURIComponent(mockTopicId)}/record/`
4. 拦截器转发配置问题
检查PactInterceptorService是否正确将请求转发到Pact的mock服务(127.0.0.1:1234),且是否正确添加了/api前缀。若拦截器未正确处理路径前缀,会导致实际请求路径与预期不符。
内容的提问来源于stack exchange,提问作者Meenakshi

