如何使用Jest监视非默认导出的UpdateCommand类构造函数?
解决Jest监视非默认导出类UpdateCommand时断言失败的问题
你遇到的核心问题是mock的作用时机和导入方式错误,导致最终拿到的UpdateCommand是原始类而非Jest mock函数。以下是具体解决方案:
修正后的测试代码方案一(全局mock,适用于多个测试用例)
// 必须将jest.mock放在测试文件的最顶部,Jest会自动将其提升到模块执行顺序的最前面 jest.mock('@aws-sdk/lib-dynamodb', () => ({ UpdateCommand: jest.fn(), // 若代码中用到DynamoDBDocumentClient,需同步mock其导出 DynamoDBDocumentClient: { from: jest.fn(() => ({ send: jest.fn() })) } })); // 在jest.mock之后导入,确保拿到的是mock版本的类 import { UpdateCommand } from '@aws-sdk/lib-dynamodb'; import { Dynamo } from './你的Dynamo模块路径'; const permissionMock = { /* 你的测试mock数据 */ }; test('Should return an updated permission object', async () => { const mockDynamoResult = { Attributes: permissionMock }; // mock send方法 const mockSend = jest.spyOn(DynamoDBDocumentClient.prototype, 'send') .mockResolvedValue(mockDynamoResult as never); await Dynamo.createUpdatePermission(permissionMock); // 现在可以正常断言UpdateCommand的调用 expect(UpdateCommand).toHaveBeenCalled(); // 还可以进一步断言传入的input参数细节 expect(UpdateCommand).toHaveBeenCalledWith(expect.objectContaining({ TableName: '你的表名', Key: { id: permissionMock.id } // 添加你需要验证的其他input属性 })); // 清理mock,避免影响其他测试用例 mockSend.mockRestore(); });
修正后的测试代码方案二(单例mock,仅影响当前测试用例)
如果不想全局mock该模块,可以使用jest.doMock配合动态导入:
const permissionMock = { /* 你的测试mock数据 */ }; test('Should return an updated permission object', async () => { const mockDynamoResult = { Attributes: permissionMock }; // 使用jest.doMock,不会被Jest自动提升,仅对当前测试生效 jest.doMock('@aws-sdk/lib-dynamodb', () => ({ UpdateCommand: jest.fn(), DynamoDBDocumentClient: { from: jest.fn(() => ({ send: jest.fn().mockResolvedValue(mockDynamoResult as never) })) } })); // 动态导入模块,确保拿到mock后的版本 const { UpdateCommand } = require('@aws-sdk/lib-dynamodb'); const { Dynamo } = require('./你的Dynamo模块路径'); await Dynamo.createUpdatePermission(permissionMock); expect(UpdateCommand).toHaveBeenCalled(); });
问题根源解释
- jest.mock的提升机制:Jest会自动将所有
jest.mock调用提升到模块代码的最顶部执行,你把它写在test函数内部时,模块导入(比如import { UpdateCommand })已经加载了原始类,导致后续拿到的不是mock函数。 - 导入时机错误:必须在
jest.mock之后导入目标模块,才能获取到mock版本的导出对象,否则拿到的始终是原始类。
内容的提问来源于stack exchange,提问作者user2691402
相关产品推荐
相关产品推荐

