无法使用Jest模拟npm模块@aws-sdk/cloudfront-signer的getSignedUrl函数
解决Jest无法Mock @aws-sdk/cloudfront-signer中getSignedUrl的问题
正确Mock方式示例
直接在测试文件顶部使用jest.mock模拟模块的命名导出,确保mock优先于被测试模块的加载:
// 测试文件开头,必须先执行mock jest.mock('@aws-sdk/cloudfront-signer', () => ({ getSignedUrl: jest.fn(() => 'mocked-cloudfront-signed-url') })); // 引入被测试模块和mock的函数 import { getSignedUrl } from '@aws-sdk/cloudfront-signer'; import { generateSignedCloudfrontUrl } from './your-target-file'; test('验证getSignedUrl被正确调用并返回mock值', () => { const result = generateSignedCloudfrontUrl(); // 检查调用参数是否匹配 expect(getSignedUrl).toHaveBeenCalledWith(expect.objectContaining({ url: 'test value', keyPairId: 'test value', dateLessThan: 'test value', privateKey: 'test value' })); // 检查返回值是否为mock值 expect(result).toBe('mocked-cloudfront-signed-url'); });
动态修改Mock返回值
如果需要在不同测试用例中返回不同结果,可以保留mock函数的引用,动态设置返回值:
jest.mock('@aws-sdk/cloudfront-signer', () => ({ getSignedUrl: jest.fn() })); import { getSignedUrl } from '@aws-sdk/cloudfront-signer'; import { generateSignedCloudfrontUrl } from './your-target-file'; test('第一个测试用例返回特定值', () => { getSignedUrl.mockReturnValue('first-test-signed-url'); expect(generateSignedCloudfrontUrl()).toBe('first-test-signed-url'); }); test('第二个测试用例返回另一个值', () => { getSignedUrl.mockReturnValue('second-test-signed-url'); expect(generateSignedCloudfrontUrl()).toBe('second-test-signed-url'); });
常见失效原因排查
- 加载顺序错误:必须先执行
jest.mock,再引入被测试的模块。如果先导入被测试文件,原模块会被提前加载,mock无法生效。 - SDK模块类型兼容问题:@aws-sdk系列是ES模块,确保Jest配置支持ES模块(可在
jest.config.js中配置transform: { '^.+\\.jsx?$': 'babel-jest' },并安装babel相关依赖)。 - 工具冲突:不要同时使用
rewire或aws-sdk-mock,这类工具对新版@aws-sdk支持不佳,且容易和Jest原生mock机制冲突。 - 导出结构误判:确认
getSignedUrl是命名导出而非默认导出,你的代码中用import { getSignedUrl }说明是命名导出,mock时要对应结构。
内容的提问来源于stack exchange,提问作者Mr.X
相关产品推荐
相关产品推荐

