React Native用Jest测react-native-sha256原实现报错解决方法
问题原因
报错核心是Jest测试运行在纯JavaScript环境(Node/jsdom),不存在React Native运行时注入的原生模块对象NativeModules.sha256Lib,react-native-sha256库内部直接读取该对象的方法时,就会触发Cannot read property 'sha256' of undefined错误。
之前写的mock只是透传了库本身的JS代码,并没有补上缺失的原生层依赖,所以依然会报错。
解决方案
根据测试需求可选择以下两种实现方式:
方案1:注入纯JS实现的SHA256逻辑,验证真实哈希计算结果
如果测试需要真实计算哈希值、验证不同输入的输出差异(比如验证大小写不同的字符串哈希输出逻辑),可以直接mock React Native的NativeModules,用纯JS实现的SHA256方法替换原生模块,计算结果和原生实现完全一致。
步骤如下:
- 安装纯JS版的sha256依赖作为测试依赖:
npm install js-sha256 --save-dev
- 编写测试用例时提前mock react-native的NativeModules,注入sha256Lib的实现:
import { sha256 } from 'react-native-sha256'; import { sha256 as jsSha256 } from 'js-sha256'; import { NativeModules } from 'react-native'; // mock react-native 原生模块 jest.mock('react-native', () => ({ NativeModules: { sha256Lib: { sha256: jest.fn((data) => Promise.resolve(jsSha256(data))), sha1: jest.fn() // 需要测试sha1时补充对应JS实现即可 } } })); describe('sha256 逻辑测试', () => { it('大小写不同的字符串哈希结果不一致', async () => { const a = await sha256('parameter'); const b = await sha256('PaRaMeTeR'); // 注意:SHA256对输入大小写敏感,两个值不相等,原测试用例的断言写反了 expect(a).not.toEqual(b); // 可通过已知值断言验证结果正确性 expect(a).toEqual('63f6fe797026d794e0dc3e2bd279aee19dd2f8db67488172a644bb68792a570c'); }); it('业务函数doSomething调用sha256逻辑符合预期', async () => { // 导入自身业务代码 const { doSomething } = require('./your-business-code-path'); await doSomething('test'); // 验证sha256被正确传参调用 expect(NativeModules.sha256Lib.sha256).toHaveBeenCalledWith('test'); }); });
方案2:完全mock react-native-sha256库,不验证真实哈希计算
如果不需要验证哈希本身的计算结果,只需要验证业务代码是否正确调用了sha256方法、处理了返回值,可以直接mock整个库,不需要引入额外依赖:
import { doSomething } from './your-business-code-path'; // 直接mock整个库 jest.mock('react-native-sha256', () => ({ sha256: jest.fn(() => Promise.resolve('mock-hash-value')) })); import { sha256 } from 'react-native-sha256'; describe('doSomething 业务逻辑测试', () => { it('调用doSomething时会正确传入参数给sha256', async () => { await doSomething('test-input'); expect(sha256).toHaveBeenCalledWith('test-input'); // 后续可验证业务逻辑是否正确处理了mock的hash值 }); });
补充说明
不要直接用jest.requireActual('react-native-sha256')透传真实库代码,除非已经提前补全了它依赖的所有原生层mock,否则必然会因为缺失原生运行环境报错。单元测试场景下优先用纯JS实现替换原生依赖,运行速度更快,也不需要依赖iOS/Android原生编译环境。
内容的提问来源于stack exchange,提问作者Andrey Solera
相关产品推荐
相关产品推荐

