如何在 NestJS 中模拟存储库、服务和控制器(Typeorm 和 Jest)

sun*_*aem 6 node.js typescript jestjs typeorm nestjs

我是打字稿的新手。我的 Nestjs 项目应用程序是这样的。我正在尝试使用存储库模式,所以我分离了业务逻辑(服务)和持久化逻辑(存储库)

用户库

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';

import { UserEntity } from './entities/user.entity';

@Injectable()
export class UserRepo {
  constructor(@InjectRepository(UserEntity) private readonly repo: Repository<UserEntity>) {}

  public find(): Promise<UserEntity[]> {
    return this.repo.find();
  }
}
Run Code Online (Sandbox Code Playgroud)

用户服务

import { Injectable } from '@nestjs/common';
import { UserRepo } from './user.repository';

@Injectable()
export class UserService {
  constructor(private readonly userRepo: UserRepo) {}

  public async get() {
   return this.userRepo.find();
  }
}
Run Code Online (Sandbox Code Playgroud)

用户控制器

import { Controller, Get } from '@nestjs/common';

import { UserService } from './user.service';

@Controller('/users')
export class UserController {
  constructor(private readonly userService: UserService) {}

  // others method //

  @Get()
  public async getUsers() {
    try {
      const payload = this.userService.get();
      return this.Ok(payload);
    } catch (err) {
      return this.InternalServerError(err);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

如何为存储库、服务和控制器创建单元测试而不实际将数据持久化或检索到数据库(使用模拟)?

Jay*_*iel 9

使用 Nest 公开的测试工具可以很容易地在 NestJS 中进行模拟@nestjs/testing。简而言之,您需要为要模拟的依赖项创建一个自定义提供程序,这就是全部。然而,看一个例子总是更好,所以这里有一个控制器模拟的可能性:

describe('UserController', () => {
  let controller: UserController;
  let service: UserService;
  beforeEach(async () => {
    const moduleRef = await Test.createTestingModule({
      controllers: [UserController],
      providers: [
        {
          provide: UserService,
          useValue: {
            get: jest.fn(() => mockUserEntity) // really it can be anything, but the closer to your actual logic the better
          }
        }
      ]
    }).compile();
    controller = moduleRef.get(UserController);
    service = moduleRef.get(UserService);
  });
});
Run Code Online (Sandbox Code Playgroud)

从那里你可以继续编写你的测试。这与使用 Nest 的 DI 系统的所有测试的设置几乎相同,唯一需要注意的是@InjectRepository()@InjectModel()(Mongoose 和 Sequilize 装饰器)之类的东西,您需要在其中使用getRepositoryToken()getModelToken()用于注入令牌。如果您正在寻找更多示例,请查看此存储库