TypeScript集成pact-node遇超时与AWS X-Ray错误求解决方案
解决Pact-Node TypeScript实现中的超时与AWS X-Ray错误问题
嘿,我来帮你拆解下遇到的两个问题——Mocha超时错误和AWS X-Ray上下文缺失问题,咱们一步步来解决:
一、先搞定超时与语法错误
第一个before all hook超时,大概率是两个原因:Mocha默认的2000ms不足以让Pact完成初始化,再加上你的代码里有几处语法错误直接导致执行异常!
1. 修正代码里的语法bug
看你添加交互的那段代码,有三处明显的语法问题:
state: 'item present in database,字符串未闭合,少了末尾的单引号path: 'path_to_my_api_endpoint,同样字符串未闭合,且API路径通常要以/开头,建议改成'/path_to_my_api_endpoint'- 虽然不是语法错误,但要确保
uponReceiving是交互对象的正确键名
修正后的交互代码如下:
return provider.addInteraction({ state: 'item present in database', uponReceiving: 'a request for items', withRequest: { method: 'GET', path: '/path_to_my_api_endpoint', headers: { Accept: 'application/json' }, }, willRespondWith: { status: 200, headers: { 'Content-Type': 'application/json' }, body: EXPECTED_BODY, }, });
2. 给Mocha设置更长的超时时间
Pact启动Mock服务需要一定时间,默认的2000ms经常不够用。你可以在before和after hook中使用普通函数(别用箭头函数,否则无法获取this)来设置超时:
before(function() { this.timeout(10000); // 给10秒足够初始化Mock服务 return provider.setup(); }); after(function() { this.timeout(10000); return provider.finalize(); });
二、解决AWS X-Ray的上下文错误
第二个错误是X-Ray无法获取上下文,这说明你的myService集成了AWS X-Ray,但测试环境中没有初始化X-Ray的上下文。最简单的解决方法是在测试文件开头设置环境变量,让X-Ray遇到上下文缺失时只打日志而不抛出错误:
// 放在测试文件最顶部 process.env.AWS_XRAY_CONTEXT_MISSING = 'LOG_ERROR';
如果你的测试场景根本不需要X-Ray,也可以在测试环境中跳过加载X-Ray的相关代码。
三、完整的TypeScript Pact示例
我把你的代码修正并整理成了可直接参考的完整示例,包含了所有注意事项:
import path from 'path'; import { Pact } from '@pact-foundation/pact'; import { expect } from 'chai'; import { afterEach, before, beforeEach, describe, it, after } from 'mocha'; import { myService } from '../../main/typescript/service/test-service'; // 禁用X-Ray上下文缺失的抛出错误,避免测试失败 process.env.AWS_XRAY_CONTEXT_MISSING = 'LOG_ERROR'; describe('My Pact Test', () => { const port = 5428; let service: myService; const provider = new Pact({ port, log: path.resolve(process.cwd(), 'logs', 'pact.log'), dir: path.resolve(process.cwd(), 'pacts'), spec: 2, consumer: 'MyConsumer', provider: 'MyProvider', pactfileWriteMode: 'merge', }); const EXPECTED_BODY = [{ auctionStartTime: 1549652248000, auctionEndTime: 1549911448000, resolveTime: 1539670248000, openTimestamp: 1533496996000, closeTimestamp: 1547804158000, previewStartTime: 1549393048000, }]; before(function() { this.timeout(10000); return provider.setup(); }); after(function() { this.timeout(10000); return provider.finalize(); }); afterEach(() => provider.verify()); // 每次测试前初始化service,确保请求指向Mock服务地址 beforeEach(() => { service = new myService(`http://localhost:${port}`); }); describe('should get items', () => { before(() => { return provider.addInteraction({ state: 'item present in database', uponReceiving: 'a request for items', withRequest: { method: 'GET', path: '/path_to_my_api_endpoint', headers: { Accept: 'application/json' }, }, willRespondWith: { status: 200, headers: { 'Content-Type': 'application/json' }, body: EXPECTED_BODY, }, }); }); it('returns the correct response', (done) => { service.getInfo('123', '123') .then((response: any) => { expect(response.data).to.eql(EXPECTED_BODY); done(); }) .catch(done); // 一定要捕获错误并传给done,否则会触发超时! }); }); });
几个额外的小提醒
- 确保你的
myService请求地址指向Pact的Mock服务(即http://localhost:${port}),不要指向真实API! - 在
it块的Promise链中一定要添加catch(done),否则请求失败时Mocha会一直等待直到超时。 - 目前官方推荐使用
@pact-foundation/pact包,pact-node已经被整合到该包中,无需单独引用。
内容的提问来源于stack exchange,提问作者user1523236
相关产品推荐
相关产品推荐

