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
相关产品推荐
相关产品推荐

