node.js - Integrationstest med TypeORM


Jag gör ett integrationstest genom att skicka förfrågningar till min utvecklingsserver med Supertest. Men jag har problem med hur man lägger in data i databasen. Till exempel, innan jag kör ett GET-test, vill jag infoga data i databasen. Men jag kan inte ens få en anslutning från TypeORM:

ConnectionNotFoundError: Connection "default" was not found.

Om jag ens får anslutningen från TypeORM, hur kan jag kapsla in ett test inom en transaktion och rulla tillbaka transaktionen efter att testet är klart för att säkerställa att integrationstestet inte påverkar en riktig databas.

I grund och botten, finns det något paket som liknar factory_bot i Rails?

describe("Templates", (): void => {
  describe("GET /api/v1/templates/{templateHash}", (): void => {
    let template: Template;
    beforeEach(
      async (): Promise<void> => {
        let templateService: TemplateService = new TemplateService();
        let connection: Connection = getConnection("default");
        template = new Template(Buffer.from(faker.random.words()), faker.random.uuid(), faker.system.fileName());
        await templateService.create(connection, template);
      },
    );
    it("should return a template", (done): void => {
      request(config.devEnvEndpoint)
        .get(`api/v1/templates/${template.templateHash}`)
        .set("Accept", "application/json")
        .expect(200)
        .end((err, response): void => {
          console.log(response);
          done();
        });
    });
  });
});

Svar #1

Det verkar som att typeorm inte plockar upp din konfiguration. Jag rekommenderar att du använder ormconfig.json-filen och har två databaskonfigurationer - en för din utveckling och en för testning.

Genom att ha två databaser behöver du inte oroa dig för transaktioner och kan radera databasen mellan tester. Jag antar att transaktioner skulle vara snabbare men det beror verkligen på ditt användningsfall (jag märkte att tester var mycket långsammare när jag gjorde många connection.synchronize()-anrop).

Då kan du använda en miljövariabel för att avgöra vilken anslutning som ska instansieras:

// db.ts
import { Connection, createConnection } from 'typeorm'

let connection: Connection | null = null

export async function getConnection() {
  if (connection) {
    return connection;
  }

  // DATABASE_CONFIG can be 'development' or 'test'
  // and should correspond to the connection names
  // in the ormconfig.json file
  connection = await createConnection(process.env.DATABASE_CONFIG);

  return connection;
}

export async function closeConnection() {
  await connection?.close();
}

Då kan du ställa in miljövariabeln och köra dina tester:

// DATABASE_CONFIG=test yarn test
import { getConnection, closeConnection } from './db'

let connection: Connection;

beforeAll(async () => {
  connection = await getConnection();
});

beforeEach(async () => {
  // Drop everything and recreate db
  await connection.synchronize(true);
});

afterAll(async () => {
  await closeConnection();
});

it('should create a connection', () => {
  expect(connection).toBeDefined();
})