TypeORM и Nest JS: создание таблиц базы данных в начале теста e2e - PullRequest
0 голосов
/ 14 февраля 2020

Я бы хотел, чтобы таблицы базы данных создавались в начале каждого теста или запуска теста, чтобы либо 1) все миграции выполнялись с тестовой базой данных, либо 2) одна миграция настраивала все таблицы (быстрее) , Это будет аналогично тому, как это делает Django .

Есть ли способ легко автоматизировать это с помощью 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' },
      ]);
    });
  });

});

Пример, основанный на этом уроке Пола Сэлмона .

1 Ответ

0 голосов
/ 14 февраля 2020

Похоже, можно sh извлечь connection из TypeORM и затем вызвать его synchronise метод.

Если кто-то 1) знает лучший способ получить соединение, 2) знает, является ли оно правильное время для звонка synchronise, пожалуйста, оставьте комментарий.

Этот вопрос обсуждался на 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();
  });
...