I have some tests and, if I run only that test individually, it works normally, but if I run all the tests, it keeps printing No description found for "Users" table. Check the table name and schema; remember, they _are_ case sensitive.
, but that doesn't makes sense, because it doesn't happen if I only run that test block.
My tests:
import { Sequelize } from 'sequelize-typescript'
import bcrypt from 'bcrypt'
import request from 'supertest'
import User from '../../src/Models/UserModel'
import app from '../../src/app'
import { setupSequelize } from '../setup/sequelizeSetup'
import RefreshTokenService from '../../src/Services/RefreshTokenServices'
import { signJwt } from '../../src/utils/JwtUtils'
describe('User Controller', () => {
let user: User
let sequelize: Sequelize
beforeEach(async () => {
sequelize = await setupSequelize()
user = await User.create({
email: 'teste@email.com',
name: 'teste',
password: 'teste',
})
})
describe('Register User', () => {
it('Deve registrar um usuário com sucesso', async () => {
const response = await request(app)
.post('/user/register')
.send({
name: 'teste',
email: 'teste2@email.com',
password: 'testeteste',
})
.expect(200)
expect(response.body).toEqual(
expect.objectContaining({
message: expect.stringContaining('Usuário Criado com Sucesso'),
})
)
})
it('Deve retornar erro 400 ao registrar usuário sem nome', async () => {
const response = await request(app)
.post('/user/register')
.send({ email: 'teste2@email.com', password: 'teste' })
.expect(400)
expect(response.body).toEqual(
expect.objectContaining({
error: expect.stringContaining(
'Não há o nome do usuário, lembre de adicionar o campo `name`'
),
})
)
})
it('Deve retornar erro 400 ao registrar usuário sem email', async () => {
const response = await request(app)
.post('/user/register')
.send({ name: 'teste', password: 'teste' })
.expect(400)
expect(response.body).toEqual(
expect.objectContaining({
error: expect.stringContaining(
'Não há o nome de email, lembre de adicionar o campo `email`'
),
})
)
})
it('Deve retornar erro 400 ao registrar usuário sem senha', async () => {
const response = await request(app)
.post('/user/register')
.send({ name: 'teste', email: 'teste2@email.com' })
.expect(400)
expect(response.body).toEqual(
expect.objectContaining({
error: expect.stringContaining(
'Não há senha para registrar-se, lembre de adicionar o campo `password`'
),
})
)
})
})
describe('Login User', () => {
beforeEach(async () => {
const hashedPass = await bcrypt.hash('teste', 10)
user.update({ password: hashedPass })
})
it('Deve logar um usuário com sucesso', async () => {
const response = await request(app)
.post('/user/login')
.send({ email: 'teste@email.com', password: 'teste' })
expect(response.body).toEqual(
expect.objectContaining({
message: expect.stringContaining('Login realizado com sucesso'),
token: expect.stringMatching(/.{680,}/),
})
)
})
it('Deve retornar erro 400 ao logar usuário sem email', async () => {
const response = await request(app)
.post('/user/login')
.send({ password: 'teste' })
.expect(400)
expect(response.body).toEqual(
expect.objectContaining({
error: expect.stringContaining(
'Não há o nome de email, lembre de adicionar o campo `email`'
),
})
)
})
it('Deve retornar erro 400 ao logar usuário sem senha', async () => {
const response = await request(app)
.post('/user/login')
.send({ email: 'teste@email.com' })
.expect(400)
expect(response.body).toEqual(
expect.objectContaining({
error: expect.stringContaining(
'Não há senha para registrar-se, lembre de adicionar o campo `password`'
),
})
)
})
})
describe('Logout User', () => {
it('Deve deslogar um usuário com sucesso', async () => {
const newAccessToken = signJwt(user.id, 'Access')
RefreshTokenService.create(newAccessToken, 1)
const response = await request(app)
.get('/user/logout')
.set('Authorization', `Bearer ${newAccessToken}`)
expect(response.body).toEqual(
expect.objectContaining({
message: expect.stringContaining(
'Você saiu da sua conta com sucesso'
),
})
)
})
})
})
Sequelize Setup Config:
// tests/setup/sequelize.ts
import { Sequelize } from 'sequelize-typescript'
import Account from '../../src/Models/AccountModel'
import EmailConfirmToken from '../../src/Models/EmailConfirmTokenModel'
import RedefinePasswordTokens from '../../src/Models/RedefinePasswordTokensModel'
import RefreshToken from '../../src/Models/RefreshTokenModel'
import User from '../../src/Models/UserModel'
export const setupSequelize = async () => {
const sequelize: Sequelize = new Sequelize({
dialect: 'sqlite',
storage: ':memory:',
models: [
Account,
EmailConfirmToken,
RedefinePasswordTokens,
RefreshToken,
User,
],
logging: false,
})
await sequelize.sync({ force: true })
return sequelize
}
EXPLANATION
On my normal app, I was using sequelize.sync()
to sync my default/production database, but it was conflicting with the sequelize.sync()
of the tests I was doing.
SOLUTION
Change the app so it only runs the sync()
if the process.env.NODE_ENV !== 'test'
solved my problem