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

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

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();
  });
});

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:

确定