You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 20:43:37