5 unit-testing node.js express supertest jestjs
我正在尝试对 Express 的身份验证中间件进行单元测试。中间件非常简单,可以在下面完整查看:
const admin = require('./../config/firebase/firebase');
// Models - User
const User = require('./../models/user');
const auth = async (req, res, next) => {
try {
// The Authorization Bearer Token sent in the header of the request needs to be decoded.
const token = req.header('Authorization').replace('Bearer ', '');
const decoded = await admin.auth().verifyIdToken(token);
// Finding that user in the database by their Firebase UID.
const user = await User.findOne({ _id: decoded.uid });
// If that user does not exist, we'll throw an error.
if (!user) {
throw new Error();
}
// Making the user accessible to the endpoint.
req.user = user;
// Proceed
next();
} catch (e) {
// HTTP 404 Unauthorized Response Status
res.status(401).send({ error: 'Please authenticate.' });
}
}
module.exports = auth;
Run Code Online (Sandbox Code Playgroud)
由于 Firebase Admin SDK 返回一个包含用户 UID 作为属性的对象,因此为了我的测试目的,我创建了一个“假令牌”,它只是一个具有 UID 属性的对象。然后我模拟 Admin SDK,使其返回传入的任何内容,如下所示:
module.exports = {
auth() {
return this;
},
verifyIdToken(token) {
return JSON.parse(token);
},
initializeApp(app) {
},
credential: {
cert() {
}
}
}
Run Code Online (Sandbox Code Playgroud)
由于 auth 中间件希望在 test 数据库中找到一个用户,我必须在beforeAll钩子中将其配置为 Jest Setup :
const userOneToken = JSON.stringify({ uid: 'example UID' });
const userOne = {
_id: 'example UID',
// ...
};
beforeAll(async () => {
await User.deleteMany();
await User.save(userOne);
app.use(auth).get('/', (req, res) => res.send());
});
Run Code Online (Sandbox Code Playgroud)
这意味着中间件总是能够得到一个 UID 作为回报,它可以用来在测试数据库中找到一个测试用户。
导入我的 Express 应用程序后,测试套件本身非常简单,只有三个测试:
const auth = require('./../../src/middleware/auth');
describe('Express Auth Middleware', () => {
test('Should return 401 with an invalid token', async () => {
await request(app)
.get('/')
.set('Authorization', 'Bearer 123')
.send()
.expect(401);
});
test('Should return 401 without an Authorization Header', async () => {
await request(app)
.get('/')
.send()
.expect(401);
});
test('Should return 200 with a valid token', async () => {
await request(app)
.get('/')
.set('Authorization', `Bearer ${userOneToken}`)
.send()
.expect(200);
});
});
Run Code Online (Sandbox Code Playgroud)
然而,似乎测试正在泄漏内存(显然通过使用--detectLeaks标志调用)。此外,似乎 Jest 还发现了上次测试留下的开放句柄。运行带有--detectOpenHandles标志的套件会根据上次测试TCPSERVERWRAP的get请求返回错误。
在这个 GitHub 问题中提出了潜在的解决方案,但没有一个对我有用。
任何解决此问题的帮助将不胜感激,因为我所有的测试套件都在泄漏内存,因为它们依赖于 Supertest。谢谢你。
| 归档时间: |
|
| 查看次数: |
1668 次 |
| 最近记录: |