KDBXWeb数据库浏览器保存正常,Vitest单元测试保存失败排查
解决Vitest测试kdbxweb数据库保存失败的问题
问题原因
- JSDOM环境的Crypto API限制:Vitest默认使用的jsdom环境中,
window.crypto.subtle的实现并不完全兼容浏览器标准,kdbxweb在执行数据库保存时调用的digest方法会因为参数类型校验失败报错。 - 测试代码调用错误:你的测试代码中调用
saveDatabase(db)时传入了参数,但vault.js中的saveDatabase函数并未接收参数,而是依赖全局变量vault,虽不是直接报错原因,但会导致逻辑混淆。
解决方案
步骤1:替换JSDOM的Crypto实现
安装兼容浏览器标准的WebCrypto库:
npm install -D @peculiar/webcrypto
创建测试前置文件test.setup.js,替换window.crypto:
import { Crypto } from '@peculiar/webcrypto'; // 替换jsdom默认的crypto实现 window.crypto = new Crypto(); window.crypto.subtle = window.crypto.subtle;
修改vite.config.js,配置测试时加载这个前置文件:
'use strict'; import { defineConfig } from 'vite'; export default defineConfig({ test: { globals: true, environment: 'jsdom', include: ['**/*.test.js'], coverage: { provider: 'v8', reporter: ['text', 'json', 'html'] }, setupFiles: ['./test.setup.js'] // 添加这一行 } })
步骤2:修正测试代码的调用错误
修改测试中saveDatabase的调用方式,去掉多余的参数:
import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import { init, createDatabase, saveDatabase, loadDatabase, clearDatabase } from '../src/vault'; import * as kdbxweb from 'kdbxweb'; describe('Vault Kxdb Tests', () => { beforeEach(() => { init(); }); afterEach(() => { clearDatabase(); }); it('should create a new database', async () => { const db = await createDatabase('test'); expect(db).toBeDefined(); }); it('should save the database', async () => { await createDatabase('test'); // create已经将vault赋值为当前db const arrayBuffer = await saveDatabase(); // 移除多余的db参数 expect(arrayBuffer).toBeDefined(); }); it('should load the database', async () => { await createDatabase('test'); const arrayBuffer = await saveDatabase(); // 移除多余的db参数 const loadedDb = await loadDatabase(arrayBuffer, 'test'); expect(loadedDb).toBeDefined(); }); });
步骤3:(可选)确保kdbxweb使用正确的Crypto实例
在vault.js开头添加一行,强制kdbxweb使用当前环境的subtle:
import * as kdbxweb from 'kdbxweb'; const VAULT_DB_NAME = 'Sample Vault'; const VAULT_DB_GROUP_NAME = 'Sample Group'; const subtle = window.crypto.subtle; kdbxweb.Crypto.setSubtle(subtle); // 添加这一行 let vault = null; // ... 其余代码不变
验证
运行测试命令:
npm run test
此时数据库创建、保存、加载的测试应该都能正常通过。
内容的提问来源于stack exchange,提问作者stwissel
相关产品推荐
相关产品推荐

