简体   繁体   English

如何玩笑模拟 nestjs 导入?

[英]How to jest mock nestjs imports?

I want to write a unit test for my nestjs 'Course' repository service (a service that has dependencies on Mongoose Model and Redis).我想为我的 nestjs“课程”存储库服务(一个依赖于 Mongoose 模型和 Redis 的服务)编写单元测试。

courses.repository.ts: course.repository.ts:

    import { Injectable, HttpException, NotFoundException } from "@nestjs/common";
    import { InjectModel } from "@nestjs/mongoose"
    import { Course } from "../../../../shared/course";
    import { Model } from "mongoose";
    import { RedisService } from 'nestjs-redis';


    @Injectable({}) 
    export class CoursesRepository {

      private redisClient;
      constructor(
        @InjectModel('Course') private courseModel: Model<Course>,
        private readonly redisService: RedisService,
      ) {
        this.redisClient = this.redisService.getClient();

      }


      async findAll(): Promise<Course[]> {
        const courses = await this.redisClient.get('allCourses');
        if (!courses) {
          console.log('return from DB');
          const mongoCourses = await this.courseModel.find();
          await this.redisClient.set('allCourses', JSON.stringify(mongoCourses), 'EX', 20);
          return mongoCourses;
        }

        console.log('return from cache');
        return JSON.parse(courses);
      }
}

The test is initialized this way:测试是这样初始化的:

beforeEach(async () => {
  const moduleRef = await Test.createTestingModule({
    imports: [
      MongooseModule.forRoot(MONGO_CONNECTION,  { 
        useNewUrlParser: true,
        useUnifiedTopology: true
      }),
      MongooseModule.forFeature([
        { name: "Course", schema: CoursesSchema },
        { name: "Lesson", schema: LessonsSchema }
      ]),
      RedisModule.register({})
    ],
      controllers: [CoursesController, LessonsController],
      providers: [
         CoursesRepository,
         LessonsRepository
        ],
    }).compile();

  coursesRepository = moduleRef.get<CoursesRepository>(CoursesRepository);
  redisClient = moduleRef.get<RedisModule>(RedisModule);

});

My Course repository service has 2 dependencies - Redis and Mongoose Model (Course).我的课程存储库服务有 2 个依赖项 - Redis 和猫鼬模型(课程)。 I would like to mock both of them.我想嘲笑他们两个。

If I was mocking a provider I would use that syntax:如果我在嘲笑提供者,我会使用该语法:

providers: [
    {provide: CoursesRepository, useFactory: mockCoursesRepository},
     LessonsRepository
    ],

Can I create a mock Redis service which will be used instead of the an actual Redis service during a test?我可以创建一个模拟 Redis 服务来代替测试期间的实际 Redis 服务吗?

How ?如何 ?

Thanks, Yaron谢谢,亚伦

You can mock your RedisService just as any other dependency.您可以像任何其他依赖RedisService一样模拟您的RedisService Since you are really interested in the Redis client and not the service, you have to create an intermediate mock for the service.由于您真正对 Redis 客户端而不是服务感兴趣,因此您必须为服务创建一个中间模拟。 For mongoose, you need the getModelToken method for getting the correct injection token, see this answer :对于猫鼬,您需要getModelToken方法来获取正确的注入令牌,请参阅此答案

const redisClientMockFactory = // ...
const redisServiceMock = {getClient: () => redisClientMockFactory()}

providers: [
  { provide: RedisService, useValue: redisServiceMock },
  { provide: getModelToken('Course'), useFactory: courseModelMockFactory },
  CoursesRepository
],

Please also note, that you probably should not import modules in unit tests (unless it is a testing module).另请注意,您可能不应该在单元测试中导入模块(除非它是一个测试模块)。 See this answer on a distinction between unit and e2e tests.请参阅有关单元测试和 e2e 测试之间区别的答案

How to create mocks?如何创建模拟?

See this answer .看到这个答案

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM