如何使用 jest 和 supertest 来模拟导入的 Express 中间件?

问题描述 投票:0回答:1

我使用 supertest 连接到服务器进行测试,并且尝试使用 Jest 模拟身份验证和授权中间件。我发现了其他几个问题,我尝试将其答案结合起来这个问题是关于模拟导入的函数,然后还有几个关于模拟快速中间件的问题:thisthisonealsothis

我尝试结合这些问题的答案并得出这个

// server.ts
import express from 'express';
import { authentication } from 'auth-lib'

const server = express();

server.use(express.json());
server.use(authentication);
server.use('/someRoute', someRouter);

export { server };
// someRoute.test.ts
import { Server } from 'http';
import request from 'supertest';
import { server } from '../path/to/server'


describe('Some tests', () => {
  let app: Server;

  beforeAll(done => {
    app = server.listen(3210, done)
  });


  afterAll(done => {
    app.close(() => done())
  });

  it('POST someRoute', async () => {
    /**
     * Mocking the authentication middleware
     */
    jest.mock('auth-lib', () => ({
      __esModule: true,
      authentication: (req, res, next): void => {
        res.locals.authentication = { auth: true, authToken: 'asdasasd' };
        next();
      }
    }));
    /**
     * But it doesn't work
     */

    const res = await request(app)
      .post('/someRoute')
      .send(testData);

    expect(res.status).toEqual(200);
  });
});

这似乎不起作用。我在模拟的中间件中进行了一些记录,但执行似乎根本没有进入那里。我还有一些其他的模拟变体,但这些也不起作用

jest.mock('auth-lib', () => ({
  __esModule: true,
  authentication: jest.fn((req, res, next): void => {
    res.locals.authentication = { auth: true, authToken: 'asdasasd' };
    next();
  })
}));
jest.mock('auth-lib', () => ({
  __esModule: true,
  authentication: jest.fn().mockImplementation((req, res, next): void => {
    res.locals.authentication = { auth: true, authToken: 'asdasasd' };
    next();
  })
}));

模拟中间件以便 res 对象也被扩展并在中间件链中向前传递的正确方法是什么?

node.js express jestjs mocking supertest
1个回答
0
投票

jest.mock()
仅适用于模块范围。

auth-lib.ts

export const authentication = (req, res, next) => {
  console.log('real implementation');
};

server.ts

import express from 'express';
import { authentication } from './auth-lib';

const server = express();

server.use(express.json());
server.use(authentication);
server.post('/someRoute', (req, res) => {
  console.log('res.locals.authentication: ', res.locals.authentication);
  res.sendStatus(200);
});

export { server };

someRoute.test.ts

import request from 'supertest';
import { server } from './server';
import { authentication } from './auth-lib';

jest.mock('./auth-lib');

const authenticationmock = jest.mocked(authentication);

describe('Some tests', () => {
  it('POST someRoute', async () => {
    authenticationmock.mockImplementation((req, res, next) => {
      res.locals.authentication = { auth: true, authToken: 'asdasasd' };
      next();
    });
    const res = await request(server).post('/someRoute');
    expect(res.status).toEqual(200);
  });
});

测试结果:

  console.log
    res.locals.authentication:  { auth: true, authToken: 'asdasasd' }

      at log (stackoverflow/78639299/server.ts:9:11)

 PASS  stackoverflow/78639299/someRoute.test.ts (8.62 s)
  Some tests
    √ POST someRoute (38 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        19.408 s
Ran all test suites related to changed files.

封装版本:

"express": "^4.19.2",
"jest": "^29.7.0",
"supertest": "^7.0.0",
© www.soinside.com 2019 - 2024. All rights reserved.