要对使用Express HTTP云函数的多个端点(如POST、PUT、DELETE)进行单元测试,你需要模拟HTTP请求并验证响应。以下是一个完整的示例,展示如何使用Jest和Supertest来测试这些端点。
首先,确保你已经安装了必要的依赖:
npm install express jest supertest @google-cloud/firestore
假设你有一个简单的Express应用,使用Firestore作为数据库:
// app.js
const express = require('express');
const Firestore = require('@google-cloud/firestore');
const app = express();
app.use(express.json());
const firestore = new Firestore();
app.post('/items', async (req, res) => {
const { name } = req.body;
const itemRef = firestore.collection('items').doc();
await itemRef.set({ name });
res.status(201).send({ id: itemRef.id, name });
});
app.put('/items/:id', async (req, res) => {
const { id } = req.params;
const { name } = req.body;
const itemRef = firestore.collection('items').doc(id);
await itemRef.update({ name });
res.status(200).send({ id, name });
});
app.delete('/items/:id', async (req, res) => {
const { id } = req.params;
const itemRef = firestore.collection('items').doc(id);
await itemRef.delete();
res.status(204).send();
});
module.exports = app;
使用Jest和Supertest编写单元测试:
// app.test.js
const request = require('supertest');
const app = require('./app');
describe('Firestore Endpoints', () => {
it('should create a new item', async () => {
const res = await request(app)
.post('/items')
.send({ name: 'Test Item' })
.expect(201);
expect(res.body).toHaveProperty('id');
expect(res.body.name).toBe('Test Item');
});
it('should update an existing item', async () => {
const createRes = await request(app)
.post('/items')
.send({ name: 'Test Item' })
.expect(201);
const id = createRes.body.id;
const updateRes = await request(app)
.put(`/items/${id}`)
.send({ name: 'Updated Item' })
.expect(200);
expect(updateRes.body.name).toBe('Updated Item');
});
it('should delete an existing item', async () => {
const createRes = await request(app)
.post('/items')
.send({ name: 'Test Item' })
.expect(201);
const id = createRes.body.id;
const deleteRes = await request(app)
.delete(`/items/${id}`)
.expect(204);
});
});
确保你的Firestore配置正确,然后运行测试:
npx jest
原因:Firestore的安全规则可能阻止了测试请求。
解决方案:在测试环境中,可以暂时放宽Firestore的安全规则,或者使用测试专用的服务账户。
// 在测试环境中放宽Firestore安全规则
const firestore = new Firestore({
projectId: 'your-project-id',
keyFilename: 'path/to/service-account-file.json',
// 其他配置
});
原因:测试数据可能会污染数据库。
解决方案:在每个测试用例结束后清理测试数据。
afterEach(async () => {
const itemsRef = firestore.collection('items');
await itemsRef.where('name', '==', 'Test Item').get().then((snapshot) => {
snapshot.forEach(async (doc) => {
await doc.ref.delete();
});
});
});
通过以上步骤,你可以对Express HTTP云函数的多个端点进行单元测试,并解决常见的测试问题。
云+社区技术沙龙[第14期]
云原生正发声
T-Day
云+社区技术沙龙[第22期]
云+社区技术沙龙[第1期]
Hello Serverless 来了
云+社区技术沙龙 [第31期]
云+社区技术沙龙[第28期]
云+社区技术沙龙[第8期]
领取专属 10元无门槛券
手把手带您无忧上云