I'm trying to run some Jest tests for the auth.service.js
module, which uses Sequelize ORM. However, when I run the tests, I'm getting the following error:
FAIL tests/modules/auth/auth.service.test.js > AuthService > login > should login user and return token
TypeError: User.findOne is not a function
Here is the code for AuthService
const User = require('../../db/models/User');
const AuthService = {
doLogin: async (requestBody) => {
const { email, password } = requestBody;
const user = await User.findOne({ where: { email } });
// rest of the code
}
}
module.exports = AuthService;
And here is the test code,
import { describe, it, expect, vi, afterEach } from 'vitest';
import bcrypt from 'bcryptjs';
import SequelizeMock from 'sequelize-mock';
const { faker } = require('@faker-js/faker');
const AuthService = require('../../../src/modules/auth/auth.service');
const JwtService = require('../../../src/modules/auth/jwt.service');
vi.mock('../../../src/db/models/User', async () => {
const dbMock = new SequelizeMock();
const fakeUser = {
id: 1,
phone: faker.phone.phoneNumber('##########'),
password: faker.internet.password(8),
};
const UserMock = dbMock.define('User', fakeUser);
return UserMock;
});
describe('AuthService', () => {
afterEach(() => {
vi.restoreAllMocks();
});
describe('login', () => {
it('should login user and return token', async () => {
// Arrange
const requestBody = {
phone: faker.phone.phoneNumber('##########'),
password: faker.internet.password(8),
};
const fakeUser = {
id: faker.datatype.uuid(),
role: faker.datatype.string(4),
};
const fakeAccessToken = 'fake-access-token';
vi.spyOn(bcrypt, 'compareSync').mockImplementation(() => true);
vi.spyOn(JwtService, 'generateJWT').mockResolvedValue(fakeAccessToken);
const expected = {
...fakeUser,
accessToken: fakeAccessToken,
};
// Act
const result = await AuthService.doLogin(requestBody);
// Assert
expect(result).toEqual(expected);
});
});
});
I also tried the below answers, but none of them work:
Sequelize Model Mocking findAll and findOne using sequelize-mock and jest
vitest
was not giving me proper errors. Inside vi.mock()
we can't access outside scoped variables.
I got this error when I changed it to jest
. Now, I have changed my test runner from vitest
to jest
, and it's working. I also removed sequelize-mock
dependency as I don't need this for my use case as of now.
const bcrypt = require('bcryptjs');
const { faker } = require('@faker-js/faker');
const AuthService = require('../../../src/modules/auth/auth.service');
const JwtService = require('../../../src/modules/auth/jwt.service');
jest.mock('../../../src/db/models/User', () => {
const fakeUser = {
id: 'fake-id',
role: 'fake-role'
};
const User = {
findOne: jest.fn().mockResolvedValue(fakeUser)
};
return User;
});
describe('AuthService', () => {
describe('login', () => {
it('should login user and return token', async () => {
// Arrange
const requestBody = {
phone: faker.phone.phoneNumber('##########'),
password: faker.internet.password(8),
};
const resolvedFakeUser = {
userId: 'fake-id',
role: 'fake-role',
};
const fakeAccessToken = 'fake-access-token';
jest.spyOn(bcrypt, 'compareSync').mockImplementation(() => true);
jest.spyOn(JwtService, 'generateJWT').mockResolvedValue(fakeAccessToken);
const expected = {
...fakeUser,
accessToken: fakeAccessToken,
};
// Act
const result = await AuthService.doLogin(requestBody);
// Assert
expect(result).toEqual(expected);
});
});
});