издевательство над функцией промежуточного программного обеспечения по умолчанию в koa-jwt с помощью jest

Я использую 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  введите описание изображения здесь  введите описание изображения здесь

Мокинг всей экспортированной функции

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

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


person Naguib Ihab    schedule 06.05.2019    source источник


Ответы (1)


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

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);
    });
  });
});
person Naguib Ihab    schedule 06.05.2019