首页 > 解决方案 > 如何使用 Jest 在 PassportJS 中模拟自定义回调 passport.authenticate(...) 方法?

问题描述

我正在为一个简单的项目创建一个后端,并且我已经让 PassportJS 和本地策略工作。我想向我的控制器添加一些单元测试,但我不知道如何模拟我的 passport.authenticate 中的所有业务逻辑,它使用自定义回调。

我已经尝试使用 Jest 的 mockImplementation 创建一个方法或一个函数,但它总是给我一个 TypeError 说 passport.authenticate(...) 不是一个函数。

这是我的控制器中的“registerUser”操作,它使用 PassportJS 和本地策略上的自定义回调。

const registerUser = async (req, res, next) => {
  const userDetails = req.body;
  const userValidation = bodyValidator.register(userDetails);
  if (userValidation.statusCode === undefined) {
    passport.authenticate('localRegister', (err, user, info) => {
      if (err) throw err;
      if (info !== undefined) {
        res.status(400);
        res.send({
          status: 'error',
          message: info.message,
          statusCode: 400,
          code: 400
        });
      } else {
        req.logIn(user, async err => {
          const userData = {
            firstName: userDetails.firstName,
            lastName: userDetails.lastName,
            email: userDetails.email
          };
          await User.update(userData);
          res.status(200);
          res.send({
            message: 'Register successful!'
          });
        });
      }
    })(req, res, next);
  } else {
    res.status(userValidation.statusCode);
    res.send(userValidation);
  }
};

这就是我的测试用例现在的样子,但我不知道如何模拟验证方法。

编辑以显示更多代码


const userController = require('../userController');
const User = require('../../models/users');
const passport = require('passport');

jest.mock('../../models/users');
jest.mock('passport');

describe.only('Register user succeeds', () => {
  let send = jest.fn();
  let status = jest.fn();
  let next = jest.fn();

  let res = {
    send,
    status
  };

  afterEach(() => {
    send.mockRestore();
    status.mockRestore();
    next.mockRestore();
  });

  it('should send a response', async () => {
    const req = {
      body: {
        email: 'mock@email.com',
        password: 'mockPassword',
        firstName: 'mockFirstName',
        lastName: 'mockLastName'
      },
      logIn
    };
    passport.authenticate.mockImplementation(() => {
      req, res, () => (done(null, '1', undefined))
    });
    User.update.mockReturnValue({});
    await userController.registerUser(req, res, next);
    expect(res.status).toHaveBeenCalledTimes(1);
    expect(res.send).toHaveBeenCalledTimes(1);
  });
});

我得到一个 TypeError: passport.authenticate(...) is not a function,而我希望我可以模拟(err, user, info)来自控制器的 passport.authenticate() 的回调参数!

标签: javascriptnode.jsauthenticationpassport.js

解决方案


推荐阅读