You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jest Mock函数返回类型无法识别引发TypeScript类型错误,求助解决方案

Jest Mock函数返回类型无法识别引发TypeScript类型错误,求助解决方案

嘿,我太懂你这种对着TypeScript类型错误折腾好几个小时的郁闷了!咱们来一步步拆解并解决你遇到的这两个问题:

一、解决Sequelize Transaction的类型不匹配问题

你遇到的{ commit: Mock; rollback: Mock; }无法赋值给never类型的错误,本质是TypeScript不知道你mock的transaction对象符合Sequelize的Transaction类型。咱们可以通过以下方式修复:

  1. 首先导入Sequelize的Transaction类型:
import { Transaction } from 'sequelize';
  1. 在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(),
    },
  };
});
  1. 在测试用例里创建transaction对象时,也加上同样的类型:
const transaction: Partial<Transaction> = { commit: jest.fn(), rollback: jest.fn() };

这样TypeScript就能识别这个对象符合Transaction的结构,不会再抛出类型错误了。

二、优化bcrypt.hash的Mock类型处理

你现在用(bcrypt.hash as jest.Mock)的写法虽然能工作,但每次都写断言太麻烦,而且容易出错。咱们可以一次性把整个bcrypt模块转为Mock类型:

  1. 在mock bcrypt之后,定义一个类型化的mocked变量:
jest.mock('bcrypt', () => ({
  hash: jest.fn(),
}));

// 一次性把bcrypt转为Mock类型
const mockedBcrypt = bcrypt as jest.Mocked<typeof bcrypt>;
  1. 之后在测试用例里直接使用这个变量:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 11:13:05