Простая макетная функция паспорта с использованием Jest - PullRequest
1 голос
/ 12 марта 2019

В настоящее время я тестирую все мои маршруты, в том числе те, которые используют функцию проверки подлинности паспорта. Я пытаюсь смоделировать паспортную функцию для проверки обработки ошибок, но получаю сообщение об ошибке:

TypeError: _passport.default.authenticate(...) is not a function

Вот фактический код, который запускается в /controllers/users.js:

export const persistentLogin = (req, res, next) => {
  // Authenicate the cookie sent on the req object.
  passport.authenticate('jwt', { session: false }, async (authErr, user) => {
    // If there is an system error, send 500 error
    if (authErr) return res.sendStatus(500);

    // If no user is returned, send response showing failure.
    if (!user) {
      return res.status(200).json({
        success: 'false',
      });
    }
  })(req, res, next);
};

Вот код тестирования в /tests/controllers/users.js:

import passport from 'passport';
import { persistentLogin } from '../../controllers/users';

beforeEach(() => {
  mockResponse = () => {
    const response = {};
    response.status = jest.fn().mockReturnValue(response);
    response.json = jest.fn().mockReturnValue(response);
    response.sendStatus = jest.fn().mockReturnValue(response);
    response.clearCookie = jest.fn().mockReturnValue(response);
    response.cookie = jest.fn().mockReturnValue(response);
    return response;
  };
});

/**
 * persistentLogin Tests
 */
describe('Persistent Login Controller', () => {
  beforeEach(() => {
    req = {};

    res = mockResponse();

    validateLoginForm.mockClear();
    bcrypt.compare.mockClear();
  });

  // Passport authenication error
  test('Should show passport authenication error', async () => {
    passport.authenticate = jest.fn((authType, options, callback) => callback('This is an error', null));

    await persistentLogin(req, res);

    expect(passport.authenticate).toHaveBeenCalledTimes(1);

    expect(res.sendStatus).toHaveBeenCalledWith(500);
  });
});

Если бы мне пришлось угадывать, я бы сказал, что это как-то связано с тем, как объекты (req, res, next) передаются в живую функцию после факта. Но так как мы просто дразним функцию, я не уверен, нужен ли ей доступ к этим объектам.

РЕДАКТИРОВАТЬ # 1:

Согласно комментарию @jakemingolla, я теперь думаю, что это может быть из-за того, что Jest не запускает мой файл app.js, который определяет мою собственную стратегию JWT.

Вот код из /app.js файла:

import passport from 'passport';
import passportJWTStrategy from './utils/auth/passport';

app.use(passport.initialize());
passportJWTStrategy(passport);

И код из /utils/auth/passport.js файла:

import { Strategy } from 'passport-jwt';

/**
 * Verifies JWT payload
 *
 * @param passport The instance of passport module.
 */
export default (passport) => {
  const JWTStrategy = Strategy;

  // Setup Options Object
  const opts = {};
  opts.jwtFromRequest = req => req.cookies.jwt;
  opts.secretOrKey = process.env.PASSPORT_SECRET;

  passport.use(
    new JWTStrategy(opts, (jwtPayload, done) => {
      if (Date.now() > jwtPayload.expire_date) {
        return done('jwt expired');
      }

      return done(null, jwtPayload);
    }),
  );
};

1 Ответ

2 голосов
/ 12 марта 2019

Вам просто нужно небольшое изменение:

Ваш макет для passport.authenticate просто должен вернуть функцию :

passport.authenticate = jest.fn((authType, options, callback) => () => { callback('This is an error', null); });
...