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

Typescript+NestJS+Jest如何mock服务调用的外部公共共享函数

你可以直接通过Jest的模块Mock能力实现需求,不需要修改任何业务代码,前提是ReadFileContents是作为ES模块的导出成员使用的(也就是你在my.service.ts里是通过import语句引入的该函数),以下是具体实现方案:

方案1:单用例灵活Mock(推荐,适配多场景测试需求)

该方案可以针对单个测试用例自定义ReadFileContents的返回值/抛出异常,不会影响其他用例的执行:

  1. 首先在测试文件顶部导入ReadFileContents所在的完整模块:
import { Test, TestingModule } from '@nestjs/testing';
import { MyService } from './my.service';
// 替换为你实际存放ReadFileContents的文件路径
import * as fileUtils from './file.utils';
  1. 在测试用例中使用jest.spyOn监听该方法,自定义返回行为:
// 测试读取文件抛出异常的场景
it('should handle exceptions when reading missing .hdr file', async () => {
  // Mock ReadFileContents调用时抛出异常
  const mockReadFile = jest.spyOn(fileUtils, 'ReadFileContents')
    .mockRejectedValue(new Error('文件不存在'));

  // 给服务的私有属性赋值(如果是private属性TS报错,用[]索引访问即可绕过校验)
  service['Directory_'] = '/test/dir';
  service['BaseName_'] = 'test-file';

  // 断言GetData方法返回符合预期的错误结果
  await expect(service.GetData()).rejects.toMatchObject({
    StatusCode: 404,
    Contents: 'File not found: test-file in /test/dir'
  });

  // 可选:验证mock方法被调用时传入的参数符合预期
  expect(mockReadFile).toHaveBeenCalledWith('/test/dir', 'test-file');

  // 清理mock,避免影响其他测试用例
  mockReadFile.mockRestore();
});

// 测试正常读取文件的场景
it('should return correct result when files exist', async () => {
  const mockReadFile = jest.spyOn(fileUtils, 'ReadFileContents')
    // 第一次调用(读取正文文件)返回自定义内容
    .mockResolvedValueOnce('测试文本内容')
    // 第二次调用(读取.err状态文件)返回状态码文本
    .mockResolvedValueOnce('201');

  service['Directory_'] = '/test/dir';
  service['BaseName_'] = 'test-file';

  const result = await service.GetData();
  expect(result.Contents).toBe('测试文本内容');
  expect(result.StatusCode).toBe(201);

  // 验证两次调用的参数都符合预期
  expect(mockReadFile).toHaveBeenNthCalledWith(1, '/test/dir', 'test-file');
  expect(mockReadFile).toHaveBeenNthCalledWith(2, '/test/dir', 'test-file.err');

  mockReadFile.mockRestore();
});

方案2:全局Mock当前测试文件所有调用

如果当前测试文件所有用例都需要MockReadFileContents,可以在测试文件顶部直接全局Mock整个模块:

// 要放在导入fileUtils的语句之前
jest.mock('./file.utils', () => ({
  ReadFileContents: jest.fn()
}));

import * as fileUtils from './file.utils';

// 后续用例不需要再写jest.spyOn,直接修改mock的返回值即可
it('test xxx', async () => {
  (fileUtils.ReadFileContents as jest.Mock).mockResolvedValue('自定义内容');
  // 执行测试逻辑...
})

补充说明

如果ReadFileContents是默认导出的模块,只需要把jest.spyOn的第二个参数改为'default'即可:

jest.spyOn(fileUtils, 'default').mockResolvedValue('xxx')

内容的提问来源于stack exchange,提问作者Steven Scott

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 06:45:06