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

React Hook测试中addDeviceIdToIndexDb返回undefined问题排查

问题排查与修复方案

核心问题分析

测试失败的主要原因大概率是以下几点之一:

1. 数据库名称/版本不匹配

测试代码中手动打开的数据库是'max-maximus'、版本1,但需要确认Hook中定义的indexDbName和dbVersion常量是否与这两个值完全一致。如果Hook里用的是其他名称或版本,测试时打开的就是另一个独立数据库,自然读不到存储的值。

2. 事务未正确等待完成

虽然Hook里已经await tx.done,但测试中读取数据时,可能没有确保事务完全提交。另外fake-indexeddb在模拟IndexedDB时,对异步事务的处理需要严格遵循流程。

3. 测试环境的DB实例隔离

每次测试前未清理fake-indexeddb的状态,可能导致之前的测试数据干扰当前测试。

修复步骤

步骤1:确保数据库常量一致

检查Hook中的indexDbName和dbVersion定义,确保和测试代码中的值完全匹配:

// Hook中的常量定义(示例)
const indexDbName = 'max-maximus';
const dbVersion = 1;

步骤2:完善测试逻辑

在测试前清理数据库,读取数据时等待事务完成:

describe('should test useIndexDb functionality', () => {
  // 每次测试前清理fake-indexeddb
  beforeEach(async () => {
    await indexedDB.deleteDatabase('max-maximus');
  });

  it('should create the IndexedDB database and object stores and add deviceId after calling addDeviceIdToIndexDb', async () => {
    const {
      result: {
        current: { addDeviceIdToIndexDb },
      },
    } = renderHook(() => useIndexDb(), { wrapper });

    await act(async () => {
      await addDeviceIdToIndexDb('1234');
    });

    const db = await openDB('max-maximus', 1);
    expect(db.objectStoreNames.contains('deviceId')).toBe(true);

    const tx = db.transaction('deviceId', 'readonly');
    const store = tx.objectStore('deviceId');
    const storedDeviceId = await store.get('deviceId');
    // 等待事务完成再断言
    await tx.done;

    expect(storedDeviceId).toBe('1234');
  });
});

步骤3:添加错误验证(可选)

修改Hook的addDeviceIdToIndexDb添加返回值,便于测试时确认操作是否成功:

const addDeviceIdToIndexDb = async (id: string) => {
  try {
    const db = await openDb();
    const tx = db.transaction('deviceId', 'readwrite');
    const store = tx.objectStore('deviceId');

    await store.put(id, 'deviceId');
    await tx.done;
    return true;
  } catch (error) {
    console.error('Error adding Device ID to IndexedDB:', error);
    return false;
  }
};

// 测试中验证返回值
const operationResult = await act(async () => {
  return addDeviceIdToIndexDb('1234');
});
expect(operationResult).toBe(true);

额外注意点

  • 确保fake-indexeddb/auto在所有IndexedDB相关代码之前导入,全局模拟环境才会生效。
  • 所有涉及Hook异步操作的代码必须用act包裹,确保React状态更新和副作用被正确处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 16:11:18