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

如何在NestJs与Jest中模拟UserService的两个依赖项?

解决NestJS+Jest测试中模拟UserRepository和ProfileService的问题

第一步:修复模块路径解析错误

报错Cannot find module 'src/models/profile.models'是因为测试环境下Jest无法识别生产环境的路径别名,需要在jest.config.js中添加路径映射:

module.exports = {
  // 其他已有配置...
  moduleNameMapper: {
    '^src/(.*)$': '<rootDir>/src/$1',
  },
};

第二步:正确模拟两个依赖

模拟依赖时,需要给mock对象提供UserService中实际调用的方法,避免测试时出现方法不存在的错误。

模拟UserRepository

根据UserService中调用的方法,给mock对象添加对应方法的模拟实现:

const mockRepository = {
  addUser: jest.fn().mockResolvedValue({ id: '1', ...mockUserDTO }),
  getUser: jest.fn().mockResolvedValue(mockUserDTO),
  deleteUser: jest.fn().mockResolvedValue(true),
  getUserById: jest.fn().mockResolvedValue(mockUserDTO),
  updateUser: jest.fn().mockResolvedValue(mockUserDTO),
};

模拟ProfileService

针对UserService中调用的createProfile和deleteProfile方法,添加模拟实现:

const mockProfileService = {
  createProfile: jest.fn().mockResolvedValue(true),
  deleteProfile: jest.fn().mockResolvedValue(true),
};

修改后的完整测试代码

import { Test, TestingModule } from "@nestjs/testing";
import { UserService } from "../../src/services/user.services";
import { ProfileService } from "../../src/services/profile.service";
import { UserRepository } from "../../src/repository/user.repository";
import { getRepositoryToken } from '@nestjs/typeorm';

// 定义测试用的mock UserDTO
const mockUserDTO = {
  username: 'testuser',
  email: 'test@example.com',
  // 补充你的DTO其他必要字段
};

describe('userService', () => {
    let userService: UserService;
    // 带具体方法的mock对象
    const mockRepository = {
      addUser: jest.fn().mockResolvedValue({ id: '1', ...mockUserDTO }),
      getUser: jest.fn().mockResolvedValue(mockUserDTO),
      deleteUser: jest.fn().mockResolvedValue(true),
      getUserById: jest.fn().mockResolvedValue(mockUserDTO),
      updateUser: jest.fn().mockResolvedValue(mockUserDTO),
    };
    const mockProfileService = {
      createProfile: jest.fn().mockResolvedValue(true),
      deleteProfile: jest.fn().mockResolvedValue(true),
    };

    beforeEach(async () => {
        const module: TestingModule = await Test.createTestingModule({
            providers: [
                UserService,
                {
                    provide: getRepositoryToken(UserRepository),
                    useValue: mockRepository
                },
                {
                    provide: ProfileService,
                    useValue: mockProfileService
                },
            ],
        }).compile();

        userService = module.get<UserService>(UserService);
    });

    it('Should be defined', () => {
        expect(userService).toBeDefined();
    });

    // 示例:测试addUser方法的完整逻辑
    it('should create user and trigger profile creation', async () => {
      const result = await userService.addUser(mockUserDTO);
      expect(mockRepository.addUser).toHaveBeenCalledWith(mockUserDTO);
      expect(mockProfileService.createProfile).toHaveBeenCalledWith({ id: '1', ...mockUserDTO });
      expect(result).toEqual({ id: '1', ...mockUserDTO });
    });
});

额外注意点

  • 确保jest.config.js中的rootDir配置为项目根目录:rootDir: './'
  • 我们已经完全模拟了ProfileService的行为,测试UserService时无需关心ProfileService自身的依赖链

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 11:15:37