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

如何用Jest和TypeScript模拟FileService的uploadToS3SingleFile方法?

解决Jest+TypeScript模拟FileService的uploadToS3SingleFile方法报错问题

问题说明

尝试用Jest和TypeScript模拟自定义FileService类中的uploadToS3SingleFile方法(该方法基于multer实现S3单文件上传),运行时出现错误:

TypeError: this.fileService.uploadS3SingleFile(...) is not a function

原FileService代码

class FileService {
  public uploadToS3SingleFile = (bucketName: string, formDataKey: string) =>
    multer({
      storage: multerS3({
        s3: awsClientS3,
        bucket: bucketName,
        metadata: (req, file, cb) => {
          cb(null, { fieldName: file.fieldName });
        },
        key: (req, _file, cb) => {
          const uniqueFileName = `${Date.now()}--${req.params.name}`;
          req.fileName = uniqueFileName;
          cb(null, uniqueFileName);
        },
      }),
      fileFilter: this.fileFilter,
    }).single(formDataKey);
}

错误原因分析

  1. 方法名拼写错误:报错中的uploadS3SingleFile是笔误,实际方法名是uploadToS3SingleFile
  2. 箭头函数属性的模拟限制:uploadToS3SingleFile是类的实例箭头函数属性,而非原型方法,Jest的jest.Mocked<T>默认只处理原型方法,直接赋值mock时需注意类型和方式
  3. 返回值类型错误:该方法返回的是Express中间件函数(同步函数),不是Promise,不能用mockResolvedValueOnce

正确模拟方案

方案一:直接替换实例的箭头函数属性

import { FileService } from './path/to/file-service';
import { Request, Response, NextFunction } from 'express';

// 创建实例并转为Jest模拟类型
const fileServiceMock = new FileService() as jest.Mocked<FileService>;

// 模拟uploadToS3SingleFile,返回自定义中间件
fileServiceMock.uploadToS3SingleFile = jest.fn((_bucketName: string, _formDataKey: string) => {
  return (req: Request, res: Response, next: NextFunction) => {
    // 可根据测试需求模拟业务逻辑,比如设置req.fileName
    req.fileName = 'mock-test-file-123';
    next();
  };
});

方案二:Mock整个FileService类

// 提前mock整个FileService模块
jest.mock('./path/to/file-service', () => {
  return {
    FileService: jest.fn().mockImplementation(() => ({
      uploadToS3SingleFile: jest.fn((_bucketName, _formDataKey) => {
        return (req: Request, res: Response, next: NextFunction) => {
          req.fileName = 'mock-test-file-123';
          next();
        };
      })
    }))
  };
});

// 在测试用例中使用
import { FileService } from './path/to/file-service';
const fileServiceMock = new FileService() as jest.Mocked<FileService>;

关键注意点

  • 严格匹配方法名:确保模拟的方法名和原类中的uploadToS3SingleFile完全一致
  • 箭头函数属性的处理:对于类的实例箭头函数属性,需直接在实例或mock类实现中定义该属性
  • 返回值匹配类型:该方法返回Express中间件函数,需用mockReturnValue或直接返回函数,不能使用Promise相关的mock方法

内容的提问来源于stack exchange,提问作者Serhii Zadorozhnyi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 16:27:26