React Jest测试中使用react-secure-storage遇本地存储错误的解决咨询
问题:测试集成react-secure-storage的React组件时抛出TypeError错误
我在为集成了react-secure-storage包的React组件编写测试用例,该包会在存储数据到localStorage前加密,但测试文件运行失败,抛出TypeError: Cannot set properties of null (setting 'textBaseline')错误。相关信息如下:
错误详情
PASS src/utils/__tests__/DataStorageUtils.test.js PASS src/utils/__tests__/EncryptionUtils.test.js PASS src/utils/__tests__/KeyManagementUtils.test.js FAIL src/components/forms/__tests__/GenerateKeysForm.test.js ● Test suite failed to run TypeError: Cannot set properties of null (setting 'textBaseline') 1 | import { isEmpty } from 'lodash'; > 2 | import secureLocalStorage from 'react-secure-storage'; | ^ 3 | 4 | class DataStorageUtils { 5 | at ClientJS.getCanvasPrint (node_modules/react-secure-storage/dist/fingerprint.lib.js:214:24) at ClientJS.getFingerprint (node_modules/react-secure-storage/dist/fingerprint.lib.js:42:30) at getFingerprint (node_modules/react-secure-storage/dist/fingerprint.js:25:31) at new EncryptionService (node_modules/react-secure-storage/dist/encryption.js:33:47) at getAllLocalStorageItems (node_modules/react-secure-storage/dist/localStorageHelpers.js:32:19) at new SecureLocalStorage (node_modules/react-secure-storage/dist/index.js:57:64) at Object.<anonymous> (node_modules/react-secure-storage/dist/index.js:117:26) at Object.<anonymous> (src/utils/DataStorageUtils.js:2:1) at Object.<anonymous> (src/components/forms/GenerateKeysForm.js:6:1) at Object.<anonymous> (src/components/forms/__tests__/GenerateKeysForm.test.js:3:1) Test Suites: 1 failed, 3 passed, 4 total Tests: 13 passed, 13 total Snapshots: 0 total Time: 1.323 s
package.json配置
{ "name": "km", "version": "0.1.0", "private": true, "dependencies": { "@testing-library/jest-dom": "^5.16.5", "@testing-library/user-event": "^13.5.0", "bootstrap": "^5.2.2", "eosjs-ecc": "^4.0.7", "lodash": "^4.17.21", "react": "^18.2.0", "react-bootstrap": "^2.6.0", "react-dom": "^18.2.0", "react-router-dom": "^6.4.3", "react-scripts": "^4.0.3", "react-secure-storage": "^1.0.21", "web-vitals": "^2.1.4" }, "engines": { "node": "16.15.0" }, "scripts": { "start": "react-scripts start", "build": "set GENERATE_SOURCEMAP=false && react-scripts build", "test": "react-scripts test", "eject": "react-scripts eject" }, "eslintConfig": { "extends": [ "react-app", "react-app/jest" ] }, "browserslist": { "production": [ ">0.2%", "not dead", "not op_mini all" ], "development": [ "last 1 chrome version", "last 1 firefox version", "last 1 safari version" ] }, "devDependencies": { "@testing-library/react": "^13.4.0" } }
setupTests.js配置
// jest-dom adds custom jest matchers for asserting on DOM nodes. // allows you to do things like: // expect(element).toHaveTextContent(/react/i) // learn more: https://github.com/testing-library/jest-dom import '@testing-library/jest-dom';
请问需要添加什么配置或有什么可行的变通方案?
解决方案
这个错误是因为react-secure-storage依赖的指纹识别库需要Canvas API,但Jest的测试环境默认没有模拟Canvas。以下是几种可行的解决方法:
方案1:在setupTests.js中手动模拟Canvas API
修改setupTests.js,添加Canvas的模拟代码:
// jest-dom adds custom jest matchers for asserting on DOM nodes. // allows you to do things like: // expect(element).toHaveTextContent(/react/i) // learn more: https://github.com/testing-library/jest-dom import '@testing-library/jest-dom'; // 模拟Canvas API class MockCanvas { getContext() { return { textBaseline: '', fillText: jest.fn(), // 按需添加其他Canvas方法 }; } } global.HTMLCanvasElement = MockCanvas;
方案2:完全Mock react-secure-storage包
在测试文件顶部或setupTests.js中,用模拟实现替代真实的react-secure-storage,避开加密和指纹识别逻辑:
// 在GenerateKeysForm.test.js顶部添加 jest.mock('react-secure-storage', () => ({ getItem: jest.fn((key) => { const mockStorage = global.mockSecureStorage || {}; return mockStorage[key]; }), setItem: jest.fn((key, value) => { global.mockSecureStorage = global.mockSecureStorage || {}; global.mockSecureStorage[key] = value; }), removeItem: jest.fn((key) => { if (global.mockSecureStorage) { delete global.mockSecureStorage[key]; } }), clear: jest.fn(() => { global.mockSecureStorage = {}; }), }));
方案3:使用jest-canvas-mock库自动模拟Canvas
安装专门的Canvas模拟库:
npm install jest-canvas-mock --save-dev
然后在setupTests.js中导入:
import '@testing-library/jest-dom'; import 'jest-canvas-mock';
该库会自动模拟所有Canvas相关API,无需手动编写模拟代码。
内容的提问来源于stack exchange,提问作者XCEPTION
相关产品推荐
相关产品推荐

