英文:
Express Jest problem running test with Sequelize
问题
问题
在尝试在我的Express应用程序上运行一些Jest测试时,我遇到了这个错误:
> FAIL models/tests/user.model.test.js
● 测试套件运行失败
TypeError: Sequelize is not a constructor
2 | const path = require('path');
3 |
> 4 | const sequelize = new Sequelize({
| ^
5 | dialect: 'sqlite',
6 | storage: path.join(__dirname, 'database.sqlite'),
7 | logging: console.log // 输出日志到控制台
在 Object.<anonymous> (models/connection.js:4:19)
在 Object.require (models/user.model.js:2:19)
在 Object.require (models/__tests__/user.model.test.js:3:64)
代码
这是我的Sequelize连接的实际代码:
const Sequelize = require('sequelize'); // 也尝试了 const { Sequelize }
const path = require('path');
const sequelize = new Sequelize({
dialect: 'sqlite',
storage: path.join(__dirname, 'database.sqlite'),
logging: console.log // 输出日志到控制台
});
sequelize.authenticate()
.then(() => {
console.log('数据库连接成功建立');
})
.catch((error) => {
console.error('连接到数据库时出错:', error);
});
module.exports = sequelize;
然后这是我在user.model.js上运行的实际测试的代码:
const { DataTypes } = require('sequelize');
const bcrypt = require('bcrypt');
const { User, createUser, findUserById, findUserByUsername } =
require('../user.model.js');
jest.mock('sequelize', () => ({
define: jest.fn(),
sync: jest.fn(),
findOne: jest.fn(),
create: jest.fn(),
query: jest.fn(),
}));
jest.mock('bcrypt', () => ({
hash: jest.fn(),
}));
describe('User Model', () => {
beforeEach(() => {
jest.clearAllMocks();
});
test('应定义用户模型', () => {
expect(sequelize.define).toHaveBeenCalledTimes(1);
expect(sequelize.define).toHaveBeenCalledWith('users', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
username: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
},
password: {
type: DataTypes.STRING,
allowNull: false,
},
});
});
test('应创建用户并散列密码', async () => {
bcrypt.hash.mockResolvedValue('hashedPassword');
const username = 'testuser'
const password = 'testpassword';
const expectedUser = {
id: 1,
username,
password: 'hashedPassword',
};
User.create.mockResolvedValue(expectedUser);
const user = await createUser(username, password);
expect(User.create).toHaveBeenCalledTimes(1);
expect(User.create).toHaveBeenCalledWith({
username,
password: 'hashedPassword',
});
expect(user).toEqual(expectedUser);
expect(bcrypt.hash).toHaveBeenCalledWith(password, 10);
});
});
在我正在运行测试的user.model.js文件中,我使用 const sequelize = require('./connection.js');
导入连接模块。只有在我尝试运行测试时才会遇到问题,如果我启动服务器,它将正常启动,我可以与数据库交互。
我尝试过的
我问过ChatGPT,它说要确保我有正确的依赖项,并确保我在连接模块中正确导入sequelize。我尝试了多种不同的导入sequelize的方式,但仍然出现相同的问题。我知道正确的依赖项已安装,因为我的其他测试工作正常。
英文:
Problem
While trying to run some Jest testing on my Express application, I encounter this error:
> FAIL models/tests/user.model.test.js
● Test suite failed to run
TypeError: Sequelize is not a constructor
2 | const path = require('path');
3 |
> 4 | const sequelize = new Sequelize({
| ^
5 | dialect: 'sqlite',
6 | storage: path.join(__dirname, 'database.sqlite'),
7 | logging: console.log // Output logs to the console
at Object.<anonymous> (models/connection.js:4:19)
at Object.require (models/user.model.js:2:19)
at Object.require (models/__tests__/user.model.test.js:3:64)
Code
This is the actual code for my Sequelize connection:
const Sequelize = require('sequelize'); // also tried const { Sequelize }
const path = require('path');
const sequelize = new Sequelize({
dialect: 'sqlite',
storage: path.join(__dirname, 'database.sqlite'),
logging: console.log // Output logs to the console
});
sequelize.authenticate()
.then(() => {
console.log('Database connection established successfully');
})
.catch((error) => {
console.error('Error connecting to the database: ', error);
});
module.exports = sequelize;
Then this is the code for my actual tests im running on user.model.js:
const { DataTypes } = require('sequelize');
const bcrypt = require('bcrypt');
const { User, createUser, findUserById, findUserByUsername } =
require('../user.model.js');
jest.mock('sequelize', () => ({
define: jest.fn(),
sync: jest.fn(),
findOne: jest.fn(),
create: jest.fn(),
query: jest.fn(),
}));
jest.mock('bcrypt', () => ({
hash: jest.fn(),
}));
describe('User Model', () => {
beforeEach(() => {
jest.clearAllMocks();
});
test('Should define User model', () => {
expect(sequelize.define).toHaveBeenCalledTimes(1);
expect(sequelize.define).toHaveBeenCalledWith('users', {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
},
username: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
},
password: {
type: DataTypes.STRING,
allowNull: false,
},
});
});
test('Should create user and hash password', async () => {
bcrypt.hash.mockResolvedValue('hashedPassword');
const username = 'testuser';
const password = 'testpassword';
const expectedUser = {
id: 1,
username,
password: 'hashedPassword',
};
User.create.mockResolvedValue(expectedUser);
const user = await createUser(username, password);
expect(User.create).toHaveBeenCalledTimes(1);
expect(User.create).toHaveBeenCalledWith({
username,
password: 'hashedPassword',
});
expect(user).toEqual(expectedUser);
expect(bcrypt.hash).toHaveBeenCalledWith(password, 10);
});
});
Inside my user.model.js file that im running tests on, I import the connection module with const sequelize = require('./connection.js');
. I only run into the problem when I try and run my test, if I start the server it will start no problem and I can interact with the database.
What I've Tried
I've asked chatGPT it said to make sure that I have the right dependencies, and to make sure I import sequelize properly in the connection module. I've tried multiple different ways of importing sequelize, but same issue. I know the right dependencies are installed because my other tests work.
答案1
得分: 1
Sequelize
是由 sequelize
模块导出的一个类。所以你需要像这样模拟这个类:jest.fn(() => instance)
。
在模拟之后,Sequelize
类将变成 jest.fn(() => instance)
,
new Sequelize(/**/)
将返回 instance
。
你应该使用 Mocking Partials,这意味着我们只想模拟 Sequelize
类,并继续使用其他东西的原始实现。
import Sequelize, { DataTypes } from 'sequelize';
jest.mock('sequelize', () => {
return {
...jest.requireActual('sequelize'),
default: jest.fn(() => ({
define: jest.fn(),
sync: jest.fn(),
findOne: jest.fn(),
create: jest.fn(),
query: jest.fn(),
})),
__esModule: true,
};
});
describe('76657256', () => {
test('should pass', () => {
expect(jest.isMockFunction(Sequelize)).toBeTruthy();
expect(DataTypes.INTEGER).toBeDefined();
});
});
英文:
Sequelize
is a class exported by sequelize
module. So you need to mock the class like this: jest.fn(() => instance)
.
After mocking, the Sequelize
class will become jest.fn(() => instance)
,
new Sequelize(/**/)
will return the instance
.
You should use Mocking Partials, which means we just want to mock the Sequelize
class and keep using the original implementation of other things.
import Sequelize, { DataTypes } from 'sequelize';
jest.mock('sequelize', () => {
return {
...jest.requireActual('sequelize'),
default: jest.fn(() => ({
define: jest.fn(),
sync: jest.fn(),
findOne: jest.fn(),
create: jest.fn(),
query: jest.fn(),
})),
__esModule: true,
};
});
describe('76657256', () => {
test('should pass', () => {
expect(jest.isMockFunction(Sequelize)).toBeTruthy();
expect(DataTypes.INTEGER).toBeDefined();
});
});
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论