使用firebase-functions-test测试v2 onCall函数无法获取参数
如何为Firebase V2 onCall函数的测试正确传递参数?
我写了一个V2版本的onCall函数用于创建用户账号,代码如下:
import { HttpsError, onCall } from "firebase-functions/v2/https"; import { logger } from "firebase-functions"; import { getAuth } from "firebase-admin/auth"; const createAccount = onCall((request) => { return getAuth() .createUser({ email: request.data.email, emailVerified: false, password: request.data.password, disabled: false, }) .then((user) => { logger.log(`Successfully created new user ${user.uid} (${request.data.email})`); return `Successfully created new user ${request.data.email}`; }) .catch((error) => { // 省略冗长的错误处理代码... }); });
我按照官方文档,使用firebase-functions-test结合Mocha进行测试,测试代码如下:
it('Should complete', (done) => { const data = test.firestore.makeDocumentSnapshot({ email: "test@test.com", password: "password12345" }, 'test/123'); const wrapped = test.wrap(functions.createAccount); wrapped(data); done(); })
测试运行无报错且能创建账号,但控制台显示创建的是匿名账号,说明函数未获取到参数。我在函数开头添加参数校验代码:
if (!request.data.email) { throw new HttpsError('invalid-argument', "Must provide an email"); } if (!request.data.password) { throw new HttpsError('invalid-argument', "Must provide a password"); }
此时函数持续报错,提示request.data.email未定义。我尝试了多种方法(修改文档路径、直接传入对象、添加params选项、序列化输入等),但request.data始终无法获取指定参数。请问如何正确为该测试传递参数?
以下是我的配置文件:
package.json
{ "name": "functions", "type": "module", "scripts": { "build": "tsc", "build:watch": "tsc --watch", "serve": "npm run build && firebase emulators:start --only functions", "shell": "npm run build && firebase functions:shell", "start": "npm run shell", "deploy": "firebase deploy --only functions", "logs": "firebase functions:log", "test": "mocha --reporter spec" }, "engines": { "node": "20" }, "main": "lib/index.js", "dependencies": { "firebase": "^10.7.1", "firebase-admin": "^11.11.1", "firebase-functions": "^4.3.1", "ts-node": "^10.9.2", "tsx": "^4.7.0", "yup": "^1.3.3" }, "devDependencies": { "firebase-functions-test": "^3.1.0", "mocha": "^10.2.0", "typescript": "^4.9.0" }, "private": true }
.mocharc.json
{ "extensions": ["ts"], "spec": ["test/**/*.ts"], "node-option": [ "experimental-specifier-resolution=node", "import=tsx/esm" ] }
解决方案
问题出在测试代码的参数传递方式上:test.firestore.makeDocumentSnapshot是用来模拟Firestore文档快照的,而onCall函数的测试需要直接传递包含data字段的请求对象,而不是文档快照。
正确的测试代码应该这样写:
it('Should complete', async () => { // 改用async/await替代done回调,更简洁 const wrapped = test.wrap(functions.createAccount); // 直接传入包含data的对象,模拟onCall的request结构 const result = await wrapped({ data: { email: "test@test.com", password: "password12345" } }); assert.equal(result, "Successfully created new user test@test.com"); });
额外注意事项:
- 测试异步函数时,优先使用
async/await而非done回调,避免异步逻辑出错 - 若需要模拟用户认证上下文,可在传入的对象中添加
auth字段,示例:wrapped({ data: { ... }, auth: { uid: 'test-uid', token: { email_verified: false } } }) - 确保
firebase-functions-test初始化正确,测试前后做好资源清理
内容的提问来源于stack exchange,提问作者Reid Moffat
相关产品推荐
相关产品推荐

