javascript - 在 Sequelize 中模拟

标签 javascript node.js unit-testing jestjs sequelize.js

所以我有一个 User型号belongsTo一个 UserRole模型。我有一些代码执行以下操作:

 const user = await models.User.create({
    email,
    password: encryptedPassword,
    ...etc
  })

 await user.setUserRole(role)

所以我们创建了我们的用户,然后使用自动生成的 sequelize 函数 setUserRole 将他们与一个 Angular 色相关联。 .

我想对此进行单元测试并完成以下操作:
  describe('resolver', () => {
    Object.assign(models.User.prototype.setUserRole(), jest.fn())

    const userInfo = {
      email: 'name@example.com',
      ...etc
    }

    let mockModel = {
      User: {
        findOne: sinon.stub().resolves(null),
        create: sinon.fake.returns({
          email: 'name@example.com',
          ...etc
        }),
      },
    }

然后我运行我的代码和 create方法工作正常,但是当我尝试分配用户 Angular 色时它失败了。我收到这条消息:
TypeError: Cannot read property 'UserRoleId' of undefined
所以我试图模拟用于关联 Sequelize 提供的两个模型的内置函数,我知道这存在于实例化模型的原型(prototype)中。那么我哪里错了?

最佳答案

这是单元测试解决方案:
index.ts :

import { Sequelize, Model, DataTypes, BelongsToSetAssociationMixin } from 'sequelize';

const sequelize = new Sequelize('postgres://testuser:testpass@localhost:5430/jestjs-codelab');

export class User extends Model {
  public id!: number;
  public userRoleId!: number;
  public email!: string;
  public password!: string;

  public readonly createdAt!: Date;
  public readonly updatedAt!: Date;

  public setUserRole!: BelongsToSetAssociationMixin<UserRole, number>;
}

class UserRole extends Model {
  public id!: number;
  public role!: string;
}

User.init(
  {
    id: {
      type: DataTypes.INTEGER,
      autoIncrement: true,
      primaryKey: true,
    },
    email: {
      type: DataTypes.STRING,
      allowNull: false,
    },
    password: {
      type: DataTypes.STRING,
      allowNull: false,
    },
  },
  {
    sequelize,
    tableName: 'users',
  },
);

UserRole.init(
  {
    id: {
      type: DataTypes.INTEGER,
      autoIncrement: true,
      primaryKey: true,
    },
    role: {
      type: DataTypes.STRING,
      allowNull: false,
    },
  },
  { sequelize, tableName: 'user_roles', timestamps: false },
);

User.belongsTo(UserRole, { foreignKey: 'user_role_id' });

// sequelize.sync({ force: true }).then(async () => {
//   await UserRole.create({ id: '1', role: 'admin' });
//   const user: any = await User.create({ email: 'example@gmail.com', password: '123', user_role_id: '1' });
//   const userRole = await user.getUserRole();
//   // console.log(userRole.id);
//   console.log('user.user_role_id: ', user.user_role_id);
// });

export const models = { User, UserRole };

export async function createUser(email: string, encryptedPassword: string) {
  const user = await models.User.create({
    email,
    password: encryptedPassword,
  });
  const role = await models.UserRole.create({ role: 'admin' });
  await user.setUserRole(role);
}
index.test.ts :

import { createUser, models } from '.';

describe('59650697', () => {
  it('should create user with role', async () => {
    const mUser: any = { setUserRole: jest.fn() };
    jest.spyOn(models.User, 'create').mockResolvedValueOnce(mUser);
    const mUserRole: any = { id: 1, role: 'admin' };
    jest.spyOn(models.UserRole, 'create').mockResolvedValueOnce(mUserRole);
    const email = 'example@gmail.com';
    const encryptedPassword = '123';
    await createUser(email, encryptedPassword);
    expect(models.User.create).toBeCalledWith({ email, password: encryptedPassword });
    expect(models.UserRole.create).toBeCalledWith({ role: 'admin' });
    expect(mUser.setUserRole).toBeCalledWith(mUserRole);
  });
});

带有覆盖率报告的单元测试结果:

 PASS  src/stackoverflow/59650697/index.test.ts (11.948s)
  59650697
    ✓ should create user with role (6ms)

----------|----------|----------|----------|----------|-------------------|
File      |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files |      100 |      100 |      100 |      100 |                   |
 index.ts |      100 |      100 |      100 |      100 |                   |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        13.797s, estimated 15s

源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59650697

关于javascript - 在 Sequelize 中模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59650697/

相关文章:

c - 如何在 C 中构建静态功能测试?

javascript - 如何根据对象中的属性合并对象数组中的对象

javascript - 无论焦点如何,每次 HTML 文本输入字段中的数据更改时,我都想触发一个事件

javascript - express.js 路由器中的自定义处理程序

javascript - 在 ReactJs 中使用 NodeJS API 登录失败

node.js - 解析回调请求时出现多方错误

javascript - jQuery 检测哪个元素是可见的

c# - 如何在 ASP.NET 中的初始页面加载时触发 UpdateProgress

python - 如何在 sqlalchemy 中模拟创建时间?

unit-testing - 我应该创建一个单独的项目来进行单元测试吗?我正在使用 JUnit