Firebase云函数单元测试出现Jest超时与认证凭据无效警告
问题根因
你遇到的超时和凭证警告由两个核心原因导致:
- admin初始化冲突:生产环境运行云函数时Firebase会自动注入运行时凭证,你在
index.ts中全局调用的admin.initializeApp()在生产环境可以正常工作,但测试环境下firebase-functions-test工具已经自动完成了admin初始化,重复初始化的无凭证实例触发了凭证无效警告,同时产生了悬而未决的数据库连接,导致Jest无法正常结束测试进程。 - 异步操作未等待、测试资源未释放:你在
afterEach中执行的数据库清理操作没有加await,同时测试结束后没有主动释放测试环境资源、断开数据库连接,Jest会一直等待所有异步资源结束直到超时。
你之前能观测到数据库数据正常更新,是因为云函数本身已经执行完成,超时是测试进程资源未释放导致的,和函数逻辑无关。
解决方案
分步骤修改代码即可解决:
1. 修改index.ts的初始化逻辑,避免重复初始化
仅当没有已存在的admin app实例时才执行初始化:
import * as functions from 'firebase-functions'; const admin = require('firebase-admin'); // 新增判断,避免重复初始化 if (admin.apps.length === 0) { admin.initializeApp(); } export const database = admin.database().ref(); export const generateRandomNumber = functions.https.onCall( async(data: any, context) => { const randomNumber = Math.floor(Math.random() * 100) await database.child('random_numbers').push(randomNumber) return { randomNumber } } );
2. 修改index.test.ts,补全异步等待和资源清理逻辑
给afterEach的清理操作加await,新增afterAll钩子释放所有测试资源:
import functionsTest from 'firebase-functions-test'; const admin = require('firebase-admin'); const testEnv = functionsTest({ "databaseURL": "https://hivemind-test-a83fc-default-rtdb.firebaseio.com", "projectId": "hivemind-test-a83fc", }, './google_auth_key.json'); describe('testing random number', () => { let funcs: any; beforeAll(() => { funcs = require('../index.ts'); }); // 补全await等待异步清理完成 afterEach(async () => { await admin.database().ref('random_numbers').remove(); }); // 新增资源清理钩子,释放所有连接 afterAll(async () => { await testEnv.cleanup(); await admin.app().delete(); }); it('works', async () => { const generateRandomNumber = testEnv.wrap(funcs.generateRandomNumber); const { randomNumber } = await generateRandomNumber({}); console.log(randomNumber); const data = await admin.database().ref('random_numbers').once('value'); const dbRandomNumber = Object.values(data.val())[0]; expect(dbRandomNumber).toBe(randomNumber); }) })
修改完成后重新运行测试,凭证警告会消失,超时问题也会同步解决。
内容的提问来源于stack exchange,提问作者mithunm93
相关产品推荐
相关产品推荐

