TypeORM和NestJS:在e2e测试开始时创建数据库表

时间:2020-02-13 22:01:41

标签: jestjs nestjs typeorm

我想在每次测试或测试运行开始时创建数据库表,以便1)对测试数据库运行所有迁移,或2)一次迁移设置所有表(更快) 。 This would be on a similar fashion as Django does it

是否有一种方法可以使用TypeORM轻松地自动执行此操作,这样就无需手动维护测试数据库的副本了?自然,在相反的测试结束时,需要进行拆卸和清理工作。

当前,我的测试失败:

● User › GET /users › should return an array of users

    QueryFailedError: relation "user" does not exist

      at new QueryFailedError (../src/error/QueryFailedError.ts:9:9)
      at Query.callback (../src/driver/postgres/PostgresQueryRunner.ts:178:30)
      at Query.Object.<anonymous>.Query.handleError (../node_modules/pg/lib/query.js:145:17)
      at Connection.connectedErrorMessageHandler (../node_modules/pg/lib/client.js:214:17)
      at Socket.<anonymous> (../node_modules/pg/lib/connection.js:134:12)

显然,如果我针对e2e_test数据库手动运行迁移,则不会失败。

我的测试代码:

import { INestApplication } from '@nestjs/common';
import { Test } from '@nestjs/testing';
import { TypeOrmModule } from '@nestjs/typeorm';
import * as supertest from 'supertest';
import { Repository } from 'typeorm';

import { User } from '../src/user/user.entity';
import { UserModule } from '../src/user/user.module';

describe('User', () => {
  let app: INestApplication;
  let repository: Repository<User>;

  beforeAll(async () => {
    const module = await Test.createTestingModule({
      imports: [
        UserModule,
        TypeOrmModule.forRoot({
          type: 'postgres',
          host: 'localhost',
          port: 54320,
          username: 'local_dev',
          password: 'local_dev',
          database: 'e2e_test',
          entities: ['./**/*.entity.ts'],
          synchronize: false,
        }),
      ],
    }).compile();

    app = module.createNestApplication();
    repository = module.get('UserRepository');
    await app.init();
  });

  afterEach(async () => {
    await repository.query(`DELETE FROM users;`);
  });

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

  describe('GET /users', () => {
    it('should return an array of users', async () => {
      await repository.save([{ displayName: 'test-name-0' }, { displayName: 'test-name-1' }]);

      const { body } = await supertest
        .agent(app.getHttpServer())
        .get('/users')
        .set('Accept', 'application/json')
        .expect('Content-Type', /json/)
        .expect(200);
      expect(body).toEqual([
        { id: expect.any(Number), name: 'test-name-0' },
        { id: expect.any(Number), name: 'test-name-1' },
      ]);
    });
  });

});

Example loosely based on this tutorial by Paul Salmon

1 个答案:

答案 0 :(得分:1)

好像可以捕获TypeORM的connection,然后调用其synchronise方法。

如果有人1)知道获得连接的更好方法2)知道是否是致电synchronise的适当时机,请发表评论。

This issue was discussed on Github

describe('User', () => {
  let app: INestApplication;
  let repository: Repository<User>;

  beforeAll(async () => {
    const module = await Test.createTestingModule({
      imports: [
        UserModule,
        TypeOrmModule.forRoot({
          type: 'postgres',
          host: 'localhost',
          port: 54320,
          username: 'local_dev',
          password: 'local_dev',
          database: 'e2e_test',
          entities: ['./**/*.entity.ts'],
          synchronize: false,
        }),
      ],
    }).compile();

    app = module.createNestApplication();

    repository = module.get('UserRepository');
    const connection = repository.manager.connection;
    // dropBeforeSync: If set to true then it drops the database with all its tables and data 
    await connection.synchronize(true); 

    await app.init();
  });