You need to enable JavaScript to run this app. 如何使用Firebase Emulators配合Jest测试使用Firebase的React应用
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Firebase Emulators配合Jest测试使用Firebase的React应用

你操作的问题主要有两个:

  1. initializeTestApp返回的测试用Firebase实例没有被你的App组件使用,App内部直接调用了全局firebase对象的storage方法,而你没有初始化全局默认的[DEFAULT] Firebase实例,因此触发报错。
  2. 组件顶层直接调用异步的getDownloadURL方法,测试时没有等待异步逻辑执行完成就生成快照,即使解决了实例问题也拿不到预期的渲染结果。

解决步骤

  • 首先修改App组件,支持传入Firebase实例,同时把异步逻辑放到useEffect中避免重复触发请求:
import firebase from "firebase/app";
import 'firebase/storage'
import React, {useState, useEffect} from 'react'

// 支持外部传入firebase实例,默认使用全局实例
export default ({firebaseApp = firebase})=>{
  const [url, setUrl] = useState<null | string>(null)
  
  useEffect(() => {
    let isMounted = true
    firebaseApp
      .storage()
      .ref('path/file')
      .getDownloadURL()
      .then((v) => {
        if (isMounted) setUrl(v);
      })
    return () => {isMounted = false}
  }, [firebaseApp])

  return <div>
    {url}
  </div>
}
  • 接着修改测试代码,将初始化好的测试实例传入组件,同时等待异步逻辑执行完成再生成快照:
import {initializeTestApp, useEmulators} from '@firebase/rules-unit-testing'
import { render, waitFor } from '@testing-library/react'
import App from '../App'

useEmulators({
  storage:{
    host: 'localhost',
    port: 9199
  }
})

// 保存初始化完成的测试用Firebase实例
const testApp = initializeTestApp({
  storageBucket: "my-bucket",
  auth: { uid: "alice" }
})

describe('test', ()=>{
  it('can match snapshot', async () => {
    const { baseElement } = render(
        // 传入测试实例
        <App firebaseApp={testApp}/>
    );
    // 等待异步请求完成、内容渲染完成
    await waitFor(() => {
      expect(baseElement.textContent).not.toBeEmpty()
    })
    expect(baseElement).toMatchSnapshot();
  })
})

如果你不想修改App组件的入参,也可以在测试文件中mock firebase/app的导出,让它直接返回你初始化好的testApp,同样可以解决实例不匹配的问题。

内容的提问来源于stack exchange,提问作者Simon Tran

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.15 16:57:04