Jest Mock函数返回类型无法识别引发TypeScript类型错误,求助解决方案
Jest Mock函数返回类型无法识别引发TypeScript类型错误,求助解决方案
嘿,我太懂你这种对着TypeScript类型错误折腾好几个小时的郁闷了!咱们来一步步拆解并解决你遇到的这两个问题:
一、解决Sequelize Transaction的类型不匹配问题
你遇到的{ commit: Mock; rollback: Mock; }无法赋值给never类型的错误,本质是TypeScript不知道你mock的transaction对象符合Sequelize的Transaction类型。咱们可以通过以下方式修复:
- 首先导入Sequelize的
Transaction类型:
import { Transaction } from 'sequelize';
- 在mock models的时候,给你定义的transaction对象加上
Partial<Transaction>类型断言(Partial可以让我们只实现需要的方法,不用补全Transaction的所有属性):
jest.mock('../models/index.js', () => { const transaction: Partial<Transaction> = { commit: jest.fn(), rollback: jest.fn() }; return { sequelize: { transaction: jest.fn().mockResolvedValue(transaction), }, Users: { findOne: jest.fn(), create: jest.fn(), }, Profiles: { create: jest.fn(), }, }; });
- 在测试用例里创建transaction对象时,也加上同样的类型:
const transaction: Partial<Transaction> = { commit: jest.fn(), rollback: jest.fn() };
这样TypeScript就能识别这个对象符合Transaction的结构,不会再抛出类型错误了。
二、优化bcrypt.hash的Mock类型处理
你现在用(bcrypt.hash as jest.Mock)的写法虽然能工作,但每次都写断言太麻烦,而且容易出错。咱们可以一次性把整个bcrypt模块转为Mock类型:
- 在mock bcrypt之后,定义一个类型化的mocked变量:
jest.mock('bcrypt', () => ({ hash: jest.fn(), })); // 一次性把bcrypt转为Mock类型 const mockedBcrypt = bcrypt as jest.Mocked<typeof bcrypt>;
- 之后在测试用例里直接使用这个变量:
mockedBcrypt.hash.mockResolvedValue('hashedPassword');
这样不仅代码更简洁,TypeScript也能正确识别mock函数的类型。
修改后的关键代码示例
这里是整合了上述修改后的核心代码片段:
import { jest } from '@jest/globals'; import { AuthService } from '../../services/auth.service.js'; import bcrypt from 'bcrypt'; import models from '../../models/index.js'; import { Transaction } from 'sequelize'; // 新增导入 jest.mock('bcrypt', () => ({ hash: jest.fn(), })); const mockedBcrypt = bcrypt as jest.Mocked<typeof bcrypt>; // 新增类型化变量 jest.mock('../models/index.js', () => { const transaction: Partial<Transaction> = { commit: jest.fn(), rollback: jest.fn() }; // 加上类型 return { sequelize: { transaction: jest.fn().mockResolvedValue(transaction), }, Users: { findOne: jest.fn(), create: jest.fn(), }, Profiles: { create: jest.fn(), }, }; }); // 测试用例中替换原断言写法: // (bcrypt.hash as jest.Mock).mockResolvedValue('hashedPassword'); // 改为: // mockedBcrypt.hash.mockResolvedValue('hashedPassword');
为什么会出现这些类型错误?
本质是TypeScript对被Jest Mock的模块类型处理的问题:Jest会替换原模块的实现,但TypeScript依然会沿用原模块的类型定义,导致mock后的对象和原类型不匹配。我们需要手动告诉TypeScript这些模块已经被Mock,或者给mock对象指定符合原类型结构的类型。
备注:内容来源于stack exchange,提问作者Louis Tran
相关产品推荐
相关产品推荐

