высмеивание функции промежуточного ПО по умолчанию в koa-jwt с помощью jest - PullRequest
0 голосов
/ 06 мая 2019

Я использую koa-jwt, который в свою очередь использует jsonwebtoken.Вот моя реализация маршрутизатора:

index.ts

const jwt = require('koa-jwt');
...
// some other code
...

export const publicEndpoints = ['/', '/openapi.json', '/healthcheck'];

export default new Router<ApplicationState, ApplicationContext>()
  .use(configure)
  .use((ctx,next) => {
    console.log("REACH 02 opts",ctx,next);
    console.log("REACH 02 jwt", jwt);
  })
  .use(
    jwt({
      secret: customSecretLoader,
      audience: (jwksConfig.audience as unknown) as string,
      algorithms: ['RS256'],
    }).unless({ path: publicEndpoints })
  )
  // Public endpoints
  .use('/openapi.json', swagger)
  .use('/', helloworld)
  .use('/healthcheck', healthcheck)

  // Secure endpoints
  .get('/secure', helloworld)
  .middleware();

вызов /secure должен проходить через промежуточное ПО, которое вызывает jwt и передает маркер

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

Предыдущее было легко, мне просто нужно было вызвать безопасный маршрут:

index.test.ts

  it('Unauthenticated secure request returns 401', async () => {
    const response = await request(server).get('/secure');
    expect(response.status).toEqual(401);
  });

Последнее, однако, чтобы заставить его работать, мне нужно смоделировать вызов функции jwt() и вернуть его 200, но проблема в том, что независимо от того, что я пишу в своем тесте, я все еще называю исходную реализацию koa-jwt.

* Чтобы иметь некоторый контекст, это библиотека koa-js, которую я пытаюсь смоделировать https://github.com/koajs/jwt/blob/master/lib/index.js. Возвращает middleware(), что вызывает verify, который в свою очередь использует jsonwebtoken enter image description here enter image description here

Mockingвся экспортируемая функция

index.test.ts

`var jwt = require('koa-jwt');`

...
// some code
...

  it('Authenticated secure request returns 200', async () => {

    jwt = jest.fn(() => {
      Promise.resolve({
        status: 200,
        success: 'Token is valid'
      });
    });

    console.log("REACH 01 jwt", jwt);

    const response = await request(server).get('/secure');
    console.log("REACH RESPONSE",response);
    expect(response.status).toEqual(200);
  });

Вывод, который я получаю из этого в конединственный лог - это:

REACH 01 jwt function mockConstructor() {
        return fn.apply(this, arguments);
        }

, что я и ожидаю, но когда jwt() попадет в index.ts, я получу вывод:

    REACH 02 jwt (opts = {}) => {
        const { debug, getToken, isRevoked, key = 'user', passthrough, tokenKey } = opts;
        const tokenResolvers = [resolveCookies, resolveAuthHeader];

        if (getToken && typeof getToken === 'function') {
            tokenResolvers.unshift(getToken);
        }

        const middleware = async function jwt(ctx, next) {
            let token;
            tokenResolvers.find(resolver => token = resolver(ctx, opts));
.....

Я ожидаю, что поиздевалсяkoa-jwt что бы я видел одинаковый вывод в обоих журналах консоли.

Я попробовал несколько разных вещей, которые дали мне тот же результат: - насмешка над функцией промежуточного программного обеспечения в экспортированной функции по умолчанию в koa-js - насмешказависимость koa-js, которая составляет jsonwebtoken

Что мне не хватает?

1 Ответ

0 голосов
/ 06 мая 2019

Решение издевалось над всем модулем снаружи теста:

import....

// some other code

jest.mock('koa-jwt', () => {
  const fn = jest.fn((opts) => // 1st level i.e. jwt()
  {
    const middlewareMock = jest.fn(async (ctx, next) => { // 2nd level i.e. middleware() 
      // Unreachable
    });
    // @ts-ignore
    middlewareMock.unless = jest.fn(() => jest.fn((ctx, next) => {
      next();
    })); // 4th level i.e. middleware().unless()
    return middlewareMock;
  });
  return fn;
});

... 

describe('routes: index', () => {
  // Testing each secure endpoint with authentication
  it('Authenticated requests to secure endpoints return 200', async () => {
    secureEndpoints.forEach(async (endpoint) => {
      const response = await request(server).get(endpoint);
      expect(response.status).toEqual(200);
    });
  });
});
...