user5113508
user5113508

Reputation:

Sequelize and Jest not playing well together

To be a bit more specific, I'm using Jest's globalSetup and globalTeardown functions/files to setup my database once at the start, and then also close and drop the tables at the end.

This isn't really the best solution, but sadly it's the only one that even remotely works without errors. Ideally, I would like to be able to establish the database connection once, and then drop/clear tables and re-create them after every test suite. Usually, with other databases (specifically Mongoose/NoSQL), this could be accomplished with Jest's beforeAll/Each and afterAll/Each no problem, but sadly this results in a lot of errors with Sequelize, specifically that it tries to re-establish the database connection every time which results in a lot of port/listen errors.

The reason I say my current setup of using the global files "sort of" works, is because the setup part works perfectly, but the teardown part, AKA await db.dropAllSchemas({}); doesn't work at all. The tables are kept throughout all tests, unless I manually wipe them.

If someone has any experience with this, I would ideally like to achieve the solution I posted in the first part, but worst case I'd like to fix what I currently have so it drops tables at the end of all tests.

This is the code I'm using to try and achieve the FIRST solution (without global files), and which causes all the errors; setupTestFramework.js

import { db } from '../../src/startup/database';

beforeAll(async () => {
  await db.sync();
});

afterAll(async () => {
  await db.dropAllSchemas({});
});

This code results in the errors;

SequelizeDatabaseError: Table 'db_tests.products' doesn't exist

It also results in a sort of scatter in the tests. Some of the initial tests pass (mainly 1–2 and probably because they are on the same DB connection), but after those all test fail.

Hopefully someone can help out as I've not really been able to find a decent solution to this.

EDIT:

database.js

import config from 'config';
import Sequelize from 'sequelize';
import { info } from 'winston';

export const db = new Sequelize(
  config.get('db.database'),
  config.get('db.username'),
  config.get('db.password'),
  {
    host: config.get('db.host'),
    port: config.get('db.port'),
    dialect: 'mysql',
    operatorsAliases: false,
    logging:
      process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'test' ? null : console.log,
  }
);

export default async () => {
  try {
    await db.authenticate();
    info('Connected to database successfully...');

    await db.sync();
  } catch (error) {
    throw new Error('Unable to connect to database...');
  }
};

Upvotes: 8

Views: 6586

Answers (1)

decodedxclusive
decodedxclusive

Reputation: 401

I had an issue similar to yours, i fixed it by closing the db connection at the end of all tests.

Export your db in your database config file and import it in your test class, then you can close the connection at the end of all tests.

afterAll(() => {
    db.close()
})

Note: when you drop all schemas, it removes all tables (for postgres db), instead close the connection after each test suites.

Upvotes: 3

Related Questions