Заглушка Sinon пропускается как промежуточное программное обеспечение узла Express - PullRequest
0 голосов
/ 19 декабря 2018

Я пытаюсь проверить поведение определенного маршрута.Он продолжает запуск промежуточного программного обеспечения, даже когда я создаю заглушку.Я хочу, чтобы аутентификация события просто прошла на данный момент.Я понимаю, что это не совсем «модульный» тест на данный момент.Я получаю там.Я также немного упростил код.Вот код для проверки:

const { rejectUnauthenticated } = require('../modules/event-authentication.middleware');

router.get('/event', rejectUnauthenticated, (req, res) => {
  res.sendStatus(200);
});

Вот промежуточное ПО, которое я пытаюсь пропустить:

const rejectUnauthenticated = async (req, res, next) => {
  const { secretKey } = req.query;
  if (secretKey) {
    next();
  } else {
    res.status(403).send('Forbidden. Must include Secret Key for Event.');
  }
};

module.exports = {
  rejectUnauthenticated,
};

Тестовый файл:

const chai = require('chai');
const chaiHttp = require('chai-http');
const sinon = require('sinon');
let app;
const authenticationMiddleware = require('../server/modules/event-authentication.middleware');

const { expect } = chai;
chai.use(chaiHttp);

describe('with correct secret key', () => {
  it('should return bracket', (done) => {
    sinon.stub(authenticationMiddleware, 'rejectUnauthenticated')
      .callsFake(async (req, res, next) => next());

    app = require('../server/server.js');

    chai.request(app)
      .get('/code-championship/registrant/event')
      .end((err, response) => {
        expect(response).to.have.status(200);
        authenticationMiddleware.rejectUnauthenticated.restore();
        done();
      });
  });
});

I 'мы пробовали следующие подобные вопросы: Как смоделировать промежуточное ПО в Express, чтобы пропустить проверку подлинности для модульного теста? и это: Узел Express es6 Sinon, заглушающее промежуточное ПО, не работает , но я все ещеполучить 403 из промежуточного программного обеспечения, которое следует пропустить.Я также запустил тесты в режиме отладки, так что я знаю, что функция промежуточного программного обеспечения, которая должна быть включена, все еще работает.

Это проблема с заглушкой моего кода?Это проблема ES6?

Могу ли я реструктурировать свой код или тест, чтобы эта работа работала?

Ответы [ 2 ]

0 голосов
/ 20 декабря 2018

По предложению @ Сергея я переключился на Jest.По крайней мере, для этого конкретного случая это значительно упростило реализацию.Для тех, кто заинтересован, вот конечный результат:

const express = require('express');
const request = require('supertest');
const registrantRouter = require('../server/routers/registrant.router');

jest.mock('../server/modules/event-authentication.middleware');
const { rejectUnauthenticated } = require('../server/modules/event-authentication.middleware');

const initRegistrantRouter = () => {
  const app = express();
  app.use(registrantRouter);
  return app;
};

describe('GET /registrant', () => {
  test('It should 200 if event authentication passes', async (done) => {
    const app = initRegistrantRouter();
    rejectUnauthenticated.mockImplementation((req, res, next) => next());
    const res = await request(app).get('/event');
    expect(res).toHaveProperty('status', 200);
    done();
  });
  test('It should 403 if event authentication fails', async (done) => {
    const app = initRegistrantRouter();
    rejectUnauthenticated.mockImplementation((req, res) => res.sendStatus(403));
    const res = await request(app).get('/event');
    expect(res).toHaveProperty('status', 403);
    done();
  });
});

Спасибо также за этот полезный пост в блоге о тестировании экспресс-приложений с помощью Jest: https://codewithhugo.com/testing-an-express-app-with-supertest-moxios-and-jest/

0 голосов
/ 19 декабря 2018

Действительно проблема с заглушкой вашего кода.

Когда вам требуется файл вашего сервера

const app = require('../server/server.js');

, ваше приложение создается со всем набором промежуточного программного обеспечения, включая rejectUnauthenticatedи ссылка на него сохраняется внутри app.

Когда вы делаете

sinon.stub(authenticationMiddleware, 'rejectUnauthenticated')
  .callsFake(async (req, res, next) => next());

, вы заменяете экспортированный метод rejectUnauthenticated модуля authenticationMiddleware, но не ссылкук исходному rejectUnauthenticated, который уже сохранен.

Решение состоит в том, чтобы создать приложение (т. е. require('../server/server.js');) после , если вы издеваетесь над методом exoprted middleware:

const chai = require('chai');
const chaiHttp = require('chai-http');
const sinon = require('sinon');

// don't create app right away
let app;
const authenticationMiddleware = require('../server/modules/event-authentication.middleware');

const { expect } = chai;
chai.use(chaiHttp);

describe('with correct secret key', () => {
  it('should return bracket', (done) => {
    sinon.stub(authenticationMiddleware, 'rejectUnauthenticated')
      .callsFake(async (req, res, next) => next());

    // method is stubbed, you can create app now
    app = require('../server/server.js');

    chai.request(app)
      .get('/code-championship/registrant/event')
      .end((err, response) => {
        expect(response).to.have.status(200);
        authenticationMiddleware.rejectUnauthenticated.restore();
        done();
      });
  });
});
...