Express+TypeScript项目Jest配置及测试代码报错求助
问题排查:Express+TypeScript API测试的编译与Mock配置错误
编译错误:watchTimeFactory.build() 提示类型不可调用
错误信息:
This expression is not callable.
Type 'WatchTime' has no call signatures.ts(2349)
相关代码
测试文件 /test/unit/services/episodeService.spec.ts 片段:
it('When has no watchTime then create it', async ()=> { const watchTime: WatchTime = watchTimeFactory.build() // ... 其他代码 })
工厂文件 /test/factories/watchTime.ts:
/*some imports*/ export const watchTimeFactory = Factory.makeFactory<WatchTime>(() => ({ userId: Number(faker.random.numeric()), episodeId: Number(faker.random.numeric()), seconds: Number(faker.random.numeric()), createdAt: new Date(), updatedAt: new Date() }))
运行时错误:Mock方法无mockReturnValue
将工厂调用移到测试用例外部后,编译错误消失,但出现新错误:
TypeError: episodesQueryServiceMock.findByUserIdAndEpisodeId.mockReturnValue is not a function
相关测试代码片段
beforeEach(() =>{ jest.mock('../../../src/services/queries/episodesQueryService') jest.mock('../../../src/models/') jest.mock('../../../src/models/WatchTime') episodesQueryServiceMock = episodesQueryService as jest.Mocked<typeof episodesQueryService> })
Jest配置文件 ./jest.config.ts
import type {Config} from '@jest/types'; const config: Config.InitialOptions = { verbose: true, transform: { '^.+\\.tsx?$': 'ts-jest', }, setupFiles: ['<rootDir>/test/setup.ts'], testEnvironment: 'node', maxWorkers: 1, preset: 'ts-jest' }; export default config;
解决方案
1. 修复工厂函数编译错误
- 检查测试文件中
WatchTime的导入:确保导入的是类型定义(接口/类型别名)而非类。如果WatchTime是ORM模型类,应使用InstanceType<typeof WatchTime>作为工厂的泛型参数,而非类本身。 - 调整工厂泛型类型:
// 假设WatchTime是模型类 import { WatchTime } from '../../src/models/WatchTime'; export const watchTimeFactory = Factory.makeFactory<InstanceType<typeof WatchTime>>(() => ({ // ... 字段定义 })) - 测试文件中对应调整类型注解:
const watchTime: InstanceType<typeof WatchTime> = watchTimeFactory.build();
2. 修复Mock方法运行时错误
- 将
jest.mock移到文件顶部:Jest会自动将jest.mock提升到模块作用域最顶部,放在beforeEach中不会正确生效,导致原模块未被Mock替换。 - 调整测试文件结构:
/*some imports*/ // 移到文件顶部 jest.mock('../../../src/services/queries/episodesQueryService') jest.mock('../../../src/models/') jest.mock('../../../src/models/WatchTime') describe('Episodes Service', () => { let episodesQueryServiceMock: jest.Mocked<typeof episodesQueryService> let watchTimeInstance: jest.Mocked<WatchTimeInstance> beforeEach(() =>{ // 重置Mock状态 jest.clearAllMocks(); episodesQueryServiceMock = episodesQueryService as jest.Mocked<typeof episodesQueryService> }) // ... 测试用例 }) - 确认导出方式:如果
episodesQueryService是默认导出,需调整Mock获取方式:episodesQueryServiceMock = require('../../../src/services/queries/episodesQueryService').default as jest.Mocked<typeof episodesQueryService>
3. 额外检查点
- 确认
ts-jest与TypeScript版本兼容,避免版本冲突导致类型解析异常。 - 检查
WatchTimeInstance定义:确保它是模型实例的正确类型,而非类本身,避免watchTimeInstance未被正确Mock。
内容的提问来源于stack exchange,提问作者Jose Luiz Junior
相关产品推荐
相关产品推荐

