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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 12:11:00