Express Jest使用Sequelize运行测试时出现问题。

huangapple go评论99阅读模式
英文:

Express Jest problem running test with Sequelize

问题

问题

在尝试在我的Express应用程序上运行一些Jest测试时,我遇到了这个错误:

> FAIL models/tests/user.model.test.js
● 测试套件运行失败

  1. TypeError: Sequelize is not a constructor
  2. 2 | const path = require('path');
  3. 3 |
  4. > 4 | const sequelize = new Sequelize({
  5. | ^
  6. 5 | dialect: 'sqlite',
  7. 6 | storage: path.join(__dirname, 'database.sqlite'),
  8. 7 | logging: console.log // 输出日志到控制台
  9. Object.<anonymous> (models/connection.js:4:19)
  10. Object.require (models/user.model.js:2:19)
  11. Object.require (models/__tests__/user.model.test.js:3:64)

代码

这是我的Sequelize连接的实际代码:

  1. const Sequelize = require('sequelize'); // 也尝试了 const { Sequelize }
  2. const path = require('path');
  3. const sequelize = new Sequelize({
  4. dialect: 'sqlite',
  5. storage: path.join(__dirname, 'database.sqlite'),
  6. logging: console.log // 输出日志到控制台
  7. });
  8. sequelize.authenticate()
  9. .then(() => {
  10. console.log('数据库连接成功建立');
  11. })
  12. .catch((error) => {
  13. console.error('连接到数据库时出错:', error);
  14. });
  15. module.exports = sequelize;

然后这是我在user.model.js上运行的实际测试的代码:

  1. const { DataTypes } = require('sequelize');
  2. const bcrypt = require('bcrypt');
  3. const { User, createUser, findUserById, findUserByUsername } =
  4. require('../user.model.js');
  5. jest.mock('sequelize', () => ({
  6. define: jest.fn(),
  7. sync: jest.fn(),
  8. findOne: jest.fn(),
  9. create: jest.fn(),
  10. query: jest.fn(),
  11. }));
  12. jest.mock('bcrypt', () => ({
  13. hash: jest.fn(),
  14. }));
  15. describe('User Model', () => {
  16. beforeEach(() => {
  17. jest.clearAllMocks();
  18. });
  19. test('应定义用户模型', () => {
  20. expect(sequelize.define).toHaveBeenCalledTimes(1);
  21. expect(sequelize.define).toHaveBeenCalledWith('users', {
  22. id: {
  23. type: DataTypes.INTEGER,
  24. primaryKey: true,
  25. autoIncrement: true,
  26. },
  27. username: {
  28. type: DataTypes.STRING,
  29. allowNull: false,
  30. unique: true,
  31. },
  32. password: {
  33. type: DataTypes.STRING,
  34. allowNull: false,
  35. },
  36. });
  37. });
  38. test('应创建用户并散列密码', async () => {
  39. bcrypt.hash.mockResolvedValue('hashedPassword');
  40. const username = 'testuser'
  41. const password = 'testpassword';
  42. const expectedUser = {
  43. id: 1,
  44. username,
  45. password: 'hashedPassword',
  46. };
  47. User.create.mockResolvedValue(expectedUser);
  48. const user = await createUser(username, password);
  49. expect(User.create).toHaveBeenCalledTimes(1);
  50. expect(User.create).toHaveBeenCalledWith({
  51. username,
  52. password: 'hashedPassword',
  53. });
  54. expect(user).toEqual(expectedUser);
  55. expect(bcrypt.hash).toHaveBeenCalledWith(password, 10);
  56. });

});

在我正在运行测试的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

  1. TypeError: Sequelize is not a constructor
  2. 2 | const path = require('path');
  3. 3 |
  4. > 4 | const sequelize = new Sequelize({
  5. | ^
  6. 5 | dialect: 'sqlite',
  7. 6 | storage: path.join(__dirname, 'database.sqlite'),
  8. 7 | logging: console.log // Output logs to the console
  9. at Object.<anonymous> (models/connection.js:4:19)
  10. at Object.require (models/user.model.js:2:19)
  11. at Object.require (models/__tests__/user.model.test.js:3:64)

Code

This is the actual code for my Sequelize connection:

  1. const Sequelize = require('sequelize'); // also tried const { Sequelize }
  2. const path = require('path');
  3. const sequelize = new Sequelize({
  4. dialect: 'sqlite',
  5. storage: path.join(__dirname, 'database.sqlite'),
  6. logging: console.log // Output logs to the console
  7. });
  8. sequelize.authenticate()
  9. .then(() => {
  10. console.log('Database connection established successfully');
  11. })
  12. .catch((error) => {
  13. console.error('Error connecting to the database: ', error);
  14. });
  15. module.exports = sequelize;

Then this is the code for my actual tests im running on user.model.js:

  1. const { DataTypes } = require('sequelize');
  2. const bcrypt = require('bcrypt');
  3. const { User, createUser, findUserById, findUserByUsername } =
  4. require('../user.model.js');
  5. jest.mock('sequelize', () => ({
  6. define: jest.fn(),
  7. sync: jest.fn(),
  8. findOne: jest.fn(),
  9. create: jest.fn(),
  10. query: jest.fn(),
  11. }));
  12. jest.mock('bcrypt', () => ({
  13. hash: jest.fn(),
  14. }));
  15. describe('User Model', () => {
  16. beforeEach(() => {
  17. jest.clearAllMocks();
  18. });
  19. test('Should define User model', () => {
  20. expect(sequelize.define).toHaveBeenCalledTimes(1);
  21. expect(sequelize.define).toHaveBeenCalledWith('users', {
  22. id: {
  23. type: DataTypes.INTEGER,
  24. primaryKey: true,
  25. autoIncrement: true,
  26. },
  27. username: {
  28. type: DataTypes.STRING,
  29. allowNull: false,
  30. unique: true,
  31. },
  32. password: {
  33. type: DataTypes.STRING,
  34. allowNull: false,
  35. },
  36. });
  37. });
  38. test('Should create user and hash password', async () => {
  39. bcrypt.hash.mockResolvedValue('hashedPassword');
  40. const username = 'testuser';
  41. const password = 'testpassword';
  42. const expectedUser = {
  43. id: 1,
  44. username,
  45. password: 'hashedPassword',
  46. };
  47. User.create.mockResolvedValue(expectedUser);
  48. const user = await createUser(username, password);
  49. expect(User.create).toHaveBeenCalledTimes(1);
  50. expect(User.create).toHaveBeenCalledWith({
  51. username,
  52. password: 'hashedPassword',
  53. });
  54. expect(user).toEqual(expectedUser);
  55. expect(bcrypt.hash).toHaveBeenCalledWith(password, 10);
  56. });

});

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 类,并继续使用其他东西的原始实现。

  1. import Sequelize, { DataTypes } from 'sequelize';
  2. jest.mock('sequelize', () => {
  3. return {
  4. ...jest.requireActual('sequelize'),
  5. default: jest.fn(() => ({
  6. define: jest.fn(),
  7. sync: jest.fn(),
  8. findOne: jest.fn(),
  9. create: jest.fn(),
  10. query: jest.fn(),
  11. })),
  12. __esModule: true,
  13. };
  14. });
  15. describe('76657256', () => {
  16. test('should pass', () => {
  17. expect(jest.isMockFunction(Sequelize)).toBeTruthy();
  18. expect(DataTypes.INTEGER).toBeDefined();
  19. });
  20. });
英文:

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.

  1. import Sequelize, { DataTypes } from 'sequelize';
  2. jest.mock('sequelize', () => {
  3. return {
  4. ...jest.requireActual('sequelize'),
  5. default: jest.fn(() => ({
  6. define: jest.fn(),
  7. sync: jest.fn(),
  8. findOne: jest.fn(),
  9. create: jest.fn(),
  10. query: jest.fn(),
  11. })),
  12. __esModule: true,
  13. };
  14. });
  15. describe('76657256', () => {
  16. test('should pass', () => {
  17. expect(jest.isMockFunction(Sequelize)).toBeTruthy();
  18. expect(DataTypes.INTEGER).toBeDefined();
  19. });
  20. });

huangapple
  • 本文由 发表于 2023年7月11日 04:50:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/76657256.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定