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

NestJS测试Spec无法解析UsersService的UserModel依赖,求解决方案

NestJS测试无法解析UsersService依赖:UserModel不可用

错误信息

Nest can't resolve dependencies of the UsersService (?). Please make sure that the argument "UserModel" at index [0] is available in the RootTestModule context.

Potential solutions:
- Is RootTestModule a valid NestJS module?
- If "UserModel" is a provider, is it part of the current RootTestModule?
- If "UserModel" is exported from a separate @Module, is that module imported within RootTestModule?
  @Module({
    imports: [ /* the Module containing "UserModel" */ ]
  })

   6 |
   7 |   beforeEach(async () => {
>  8 |     const module: TestingModule = await Test.createTestingModule({
     |                                   ^
   9 |       providers: [UsersService],
  10 |     }).compile();
  11 |

项目基于NestJS+MongoDB实现对象存储,根模块已正确配置Mongoose和UsersModule,AppController的/端点测试正常,但UsersService和UsersController的测试均触发上述错误。


相关代码示例

UsersService测试代码

import { Test, TestingModule } from '@nestjs/testing';
import { UsersService } from './users.service';

describe('UsersService', () => {
  let service: UsersService;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [UsersService],
    }).compile();

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

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

UsersModule代码

import { Module } from '@nestjs/common';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { MongooseModule } from '@nestjs/mongoose';
import { User, UserSchema } from './schemas/user.schema';

@Module({
  imports: [
    MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
  ],
  controllers: [UsersController],
  providers: [UsersService],
})
export class UsersModule {}

UsersService代码

import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { User } from './schemas/user.schema';
import { Model } from 'mongoose';
import { CreateUserDto } from './dto/create-user.dto';

@Injectable()
export class UsersService {
  constructor(@InjectModel(User.name) private userModel: Model<User>) {}

  async create(createUserDto: CreateUserDto): Promise<User> {
    const user = new this.userModel(createUserDto);
    return user.save();
  }

  async findById(id: string): Promise<User> {
    return this.userModel.findById(id).exec();
  }
}

UsersController代码

import { Body, Controller, Get, Param, Post } from '@nestjs/common';
import { UsersService } from './users.service';
import { CreateUserDto } from './dto/create-user.dto';
import { User } from './schemas/user.schema';

@Controller('users')
export class UsersController {
  constructor(private usersService: UsersService) {}

  @Post()
  async create(@Body() createUserDto: CreateUserDto) {
    await this.usersService.create(createUserDto);
  }

  @Get(':id')
  async findById(@Param('id') id: string): Promise<User> {
    return this.usersService.findById(id);
  }
}

解决方案

方案1:直接导入UsersModule(最简方式)

测试模块无需单独声明UsersService,直接导入UsersModule即可自动继承模块内所有依赖配置(包括UserModel):

import { Test, TestingModule } from '@nestjs/testing';
import { UsersService } from './users.service';
import { UsersModule } from './users.module';

describe('UsersService', () => {
  let service: UsersService;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      imports: [UsersModule], // 替换原有的providers数组
    }).compile();

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

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

方案2:手动模拟UserModel(单元测试隔离)

如果需要隔离数据库依赖,可手动模拟UserModel的实现,避免连接真实数据库:

import { Test, TestingModule } from '@nestjs/testing';
import { UsersService } from './users.service';
import { getModelToken } from '@nestjs/mongoose';
import { User } from './schemas/user.schema';

describe('UsersService', () => {
  let service: UsersService;
  let mockUserModel: any;

  beforeEach(async () => {
    // 模拟UserModel核心方法
    mockUserModel = {
      findById: jest.fn().mockReturnThis(),
      exec: jest.fn(),
      save: jest.fn(),
      constructor: jest.fn().mockImplementation((dto) => ({ ...dto, save: mockUserModel.save })),
    };

    const module: TestingModule = await Test.createTestingModule({
      providers: [
        UsersService,
        {
          provide: getModelToken(User.name), // 使用Nest提供的模型注入令牌
          useValue: mockUserModel, // 注入模拟的模型对象
        },
      ],
    }).compile();

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

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

  // 示例:测试create方法逻辑
  it('should create a user', async () => {
    const createUserDto = { name: 'Test User', email: 'test@example.com' };
    mockUserModel.save.mockResolvedValue(createUserDto);
    
    const result = await service.create(createUserDto);
    expect(result).toEqual(createUserDto);
    expect(mockUserModel.save).toHaveBeenCalled();
  });
});

方案说明

  • 方案1适合集成测试,复用现有模块配置,确保测试环境与生产环境依赖一致。
  • 方案2适合单元测试,通过模拟模型隔离外部依赖,专注验证Service本身的业务逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 05:55:16