如何使用Jest测试BFF中的GraphQL错误?测试用例报错排查
解决Jest测试GraphQLError抛出断言失败的问题
问题分析
你遇到的问题有两个核心原因:
- 异步断言写法错误:原代码里
expect(await api.getCustDetail(...)).rejects.toThrow()的写法会直接执行异步函数,抛出的错误会提前终止测试,无法被rejects正确捕获。 - 实例严格匹配不适用:
toThrow(error)要求抛出的错误是完全相同的对象实例,但如果getCustDetail内部对get抛出的错误做了重新包装(比如捕获后创建新的GraphQLError抛出),或者异步流程中实例引用发生变化,就会导致断言失败。
修正方案
调整异步断言的写法,同时改用错误属性匹配而非实例匹配,以下是两种可行的修正代码:
方案1:拆分断言验证类型、消息和extensions
it.only('test getCustDetail with unsuccessful response', async () => { const message = 'api failed'; const extensions = { response: { status: 500 } }; jest.spyOn(RESTDataSource.prototype as any, 'get').mockImplementation(async () => { throw new GraphQLError(message, undefined, undefined, undefined, undefined, undefined, extensions); }); // 验证错误类型 await expect(api.getCustDetail(mockToken, mockId, mockCoId)).rejects.toBeInstanceOf(GraphQLError); // 验证错误消息 await expect(api.getCustDetail(mockToken, mockId, mockCoId)).rejects.toThrow(message); // 验证extensions属性结构 await expect(api.getCustDetail(mockToken, mockId, mockCoId)).rejects.toMatchObject({ extensions: { response: { status: 500 } } }); });
方案2:链式断言一次性验证所有条件
it.only('test getCustDetail with unsuccessful response', async () => { const message = 'api failed'; const extensions = { response: { status: 500 } }; jest.spyOn(RESTDataSource.prototype as any, 'get').mockImplementation(async () => { throw new GraphQLError(message, undefined, undefined, undefined, undefined, undefined, extensions); }); await expect(api.getCustDetail(mockToken, mockId, mockCoId)) .rejects .toBeInstanceOf(GraphQLError) .and.toMatchObject({ message, extensions }); });
关键要点
- 不要await被测试的异步函数:直接将函数调用传给
expect,由rejects处理异步错误的捕获和断言。 - 优先匹配错误属性:相比于匹配实例引用,验证错误的类型、消息、自定义属性(如
extensions)更符合实际测试场景,避免因错误包装导致的断言失败。
内容的提问来源于stack exchange,提问作者Abhi Leuva
相关产品推荐
相关产品推荐

