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

NestJS单元测试Mock Sequelize模型时findAll报错的解决求助

NestJS单元测试Mock Sequelize模型的问题解决方案

问题场景

使用NestJS构建CRUD API时,编写服务单元测试时Mock Sequelize模型出现报错,测试代码及错误信息如下:

测试代码

import { getModelToken } from "@nestjs/sequelize";
import { Test, TestingModule } from "@nestjs/testing";

import { VacanciesService } from "../../vacancies.service";
import { DepartmentsServices } from "../../../departments/departments.service";
import { Departments } from "../../../departments/model/departments.model";
import { Vacancies } from "../../model/vacancies.model";

describe("Vacancies service", () => {
  let service: VacanciesService;

  const mockSequelizeDepartments = {
    findByPk: jest.fn(),
  };

  const mockSequelizeVacancies = {
    findAll: jest.fn(),
  };

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [
        VacanciesService,
        { provide: getModelToken(Vacancies), useValue: { mockSequelizeVacancies } },
        DepartmentsServices,
        { provide: getModelToken(Departments), useValue: { mockSequelizeDepartments } },
      ],
    }).compile();

    service = module.get<VacanciesService>(VacanciesService);
  });

  it("should be defined", () => {
    expect(service).toBeDefined();
  });

  describe("List vacancies", () => {
    it("should list all vacancies and return an empty array", async () => {
      const list = await service.list();

      expect(list).toHaveLength(0);
      expect(mockSequelizeVacancies.findAll).toHaveBeenCalledTimes(1);
    });
  });
});

报错信息

TypeError: this.vacanciesModel.findAll is not a function

      57 |
      58 |   async list() {
    > 59 |     const list = await this.vacanciesModel.findAll();
         |                                            ^
      60 |
      61 |     if (!list) throw new NotFoundException("Nenhuma vaga encontrada");
      62 |

尝试修改findAll为findAll() { "Do something" }或findAll: () => { "Do something" }后仍报错。

问题原因

Mock模型的注入方式错误:你把mockSequelizeVacancies和mockSequelizeDepartments额外嵌套了一层对象,导致注入后的模型结构变为{ mockSequelizeVacancies: { findAll: jest.fn() } },服务中调用this.vacanciesModel.findAll()自然找不到对应方法。

同时,原Mock的findAll未设置返回值,即使解决注入问题,调用service.list()也会因为返回undefined触发NotFoundException。

解决步骤

  1. 修正Mock注入方式:直接将mockSequelizeVacancies和mockSequelizeDepartments作为useValue的值,移除额外的对象包裹。
  2. 设置Mock方法返回值:给findAll添加mockResolvedValue([]),确保返回空数组,避免触发服务中的异常。

修改后的测试代码

import { getModelToken } from "@nestjs/sequelize";
import { Test, TestingModule } from "@nestjs/testing";
import { NotFoundException } from "@nestjs/common";

import { VacanciesService } from "../../vacancies.service";
import { DepartmentsServices } from "../../../departments/departments.service";
import { Departments } from "../../../departments/model/departments.model";
import { Vacancies } from "../../model/vacancies.model";

describe("Vacancies service", () => {
  let service: VacanciesService;

  const mockSequelizeDepartments = {
    findByPk: jest.fn(),
  };

  const mockSequelizeVacancies = {
    findAll: jest.fn().mockResolvedValue([]), // 设置返回空数组
  };

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [
        VacanciesService,
        { provide: getModelToken(Vacancies), useValue: mockSequelizeVacancies }, // 直接传入Mock对象
        DepartmentsServices,
        { provide: getModelToken(Departments), useValue: mockSequelizeDepartments }, // 同理修正
      ],
    }).compile();

    service = module.get<VacanciesService>(VacanciesService);
  });

  it("should be defined", () => {
    expect(service).toBeDefined();
  });

  describe("List vacancies", () => {
    it("should list all vacancies and return an empty array", async () => {
      const list = await service.list();

      expect(list).toHaveLength(0);
      expect(mockSequelizeVacancies.findAll).toHaveBeenCalledTimes(1);
    });

    // 可选:测试无数据时的异常抛出逻辑
    it("should throw NotFoundException when no vacancies found", async () => {
      mockSequelizeVacancies.findAll.mockResolvedValue(null);
      await expect(service.list()).rejects.toThrow(NotFoundException);
    });
  });
});

关键说明

  • 移除useValue中的对象嵌套是核心修复点,确保注入的Mock模型直接包含所需的方法。
  • 设置mockResolvedValue可以模拟Sequelize异步查询的返回结果,让测试逻辑正常执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 12:20:28