首页 > 解决方案 > 在 NestJS e2e 测试中获取 Mongoose 实例

问题描述

我开始为我的 NestJS API 编写 e2e 测试,我想使用一个测试数据库。我在测试模块中导入了 MongooseModule,它正确使用了预期的测试数据库。

然后,我想在测试之前清除集合并重新插入固定装置。为此,我想使用 NestJS 使用的 Mongoose 实例。但是我没有成功,最后创建了第二个连接(在 beforeAll 钩子中)

我还没有找到任何解决方案来避免这种情况。

这是代码:

describe('Color', () => {
  let app: INestApplication
  let db: Connection

  beforeAll(async () => {
    db = await mongoose.createConnection(process.env.MONGO_TEST_URL, {
      useNewUrlParser: true,
      useUnifiedTopology: true,
      useCreateIndex: true
    })

    db.model('Color', ColorSchema)
  })

  beforeEach(async () => {
    const moduleFixture: TestingModule = await Test.createTestingModule({
      imports: [
        MongooseModule.forRoot(process.env.MONGO_TEST_URL, {
          useCreateIndex: true,
          useFindAndModify: false
        }),
        AppModule
      ]
    }).compile()

    await db.model('Color').deleteMany({})
    await db.model('Color').insertMany(ColorFixtures)

    app = moduleFixture.createNestApplication()
    await app.init()
  })

  afterAll(async () => {
    await db.close()
    await app.close()
  })

  it('/ (GET)', () => {
    return request(app.getHttpServer())
      .post('/graphql')
      .send({
        operationName: 'findAll',
        query: 'query findAll { colors { id name } }',
        variables: {}
      })
      .expect(200)
      .expect({})
  })
})

任何想法 ?

标签: mongoosenestjs

解决方案


我为身份验证(/注册)示例编写了自己的 e2e 测试:

afterEach是从集合中删除数据的好地方。

import { Test, TestingModule } from '@nestjs/testing';
import { INestApplication } from '@nestjs/common';
import request from 'supertest';
import { AppModule } from './../src/app.module';
import { Connection } from 'mongoose';
import { getConnectionToken } from '@nestjs/mongoose';
import { SignupUserDto } from '../src/authentication/dto/signup-user.dto';
import { UsersService } from '../src/users/users.service';

describe('Authentication (e2e)', () => {
  let app: INestApplication;
  let connection: Connection;
  let usersService: UsersService;
  beforeAll(async () => {
    const moduleFixture: TestingModule = await Test.createTestingModule({
      imports: [AppModule],
    }).compile();

    usersService = moduleFixture.get<UsersService>(UsersService);
    //connection = await moduleFixture.get(getConnectionToken());
    app = moduleFixture.createNestApplication();
    await app.init();
  });
  afterAll(async () => {
    // await connection.close(/*force:*/ true); // <-- important
    await app.close();
  });

  afterEach(async () => {
    // truncate data from DB...
    await usersService.removeAll();
  });
  describe('POST /signup', () => {
    const signupData: SignupUserDto = {
      email: 'testd@test.com',
      name: 'testuser',
      password: 'test123456',
    };

    it('should return 400 error if all inputs not provided', () => {
      let data = { ...signupData };
      delete data['password'];
      return request(app.getHttpServer())
        .post('/auth/signup')
        .send(data)
        .expect(400);
    });

    it('should return 400  if email is in use', async () => {
      await usersService.create(signupData);
      return request(app.getHttpServer())
        .post('/auth/signup')
        .send(signupData)
        .expect(400);
    });
  });
});

和 db 连接设置在app.module.ts

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      cache: true,
    }),
    MongooseModule.forRootAsync({
      inject: [ConfigService],
      useFactory: (config: ConfigService) => ({
        uri:
          config.get('NODE_ENV') === 'test'
            ? config.get<string>('MONGO_TEST_CONNECTION')
            : config.get<string>('MONGO_CONNECTION'),
        autoIndex: false,
      }),
    }),
    // add throttle based on api (REST,Graphql,Socket,...)
    UsersModule,
    AuthenticationModule,
  ]
  ,...
  });

推荐阅读