我使用 supertest 连接到服务器进行测试,并且尝试使用 Jest 模拟身份验证和授权中间件。我发现了其他几个问题,我尝试将其答案结合起来这个问题是关于模拟导入的函数,然后还有几个关于模拟快速中间件的问题:this,thisone和alsothis
我尝试结合这些问题的答案并得出这个
// 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 对象也被扩展并在中间件链中向前传递的正确方法是什么?
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",