使用react-test-renderer测试时useEffect异步更新state不生效问题
问题原因与解决方案
核心错误
你定义的模拟权限 Promise 没有触发 resolve,导致useEffect里的异步逻辑永远处于 pending 状态,await BarCodeScanner.requestPermissionsAsync()之后的setHasPermission永远不会执行,自然看不到状态更新后的渲染结果。
你原来的 Promise 写法只是在构造函数回调里返回了权限对象,没有把对象传给resolve方法,正确的模拟写法可以直接用Promise.resolve简化:
const mockPermissionPromise: Promise<PermissionResponse> = Promise.resolve({ status: PermissionStatus.GRANTED, expires: "never", granted: true, canAskAgain: true, });
修正后完整测试代码
import { BarCodeScanner, PermissionResponse, PermissionStatus } from "expo-barcode-scanner"; import React from "react"; import { create, act } from "react-test-renderer"; import BarCodeScanScreen from "../BarCodeScanScreen"; describe("BarCodeScanScreen", () => { it("renders correctly if permission is granted", async () => { // 修正:直接用resolve返回模拟的权限结果 const mockPermissionPromise: Promise<PermissionResponse> = Promise.resolve({ status: PermissionStatus.GRANTED, expires: "never", granted: true, canAskAgain: true, }); const permissionRequestSpy = jest.spyOn(BarCodeScanner, 'requestPermissionsAsync').mockReturnValue(mockPermissionPromise); let tree; await act(async () => { tree = create(<BarCodeScanScreen />); }); // 可选:主动触发一次更新,确保所有 pending 的状态变更都被应用 tree.update(<BarCodeScanScreen />); expect(permissionRequestSpy).toHaveBeenCalled(); expect(tree.toJSON()).toMatchSnapshot(); permissionRequestSpy.mockRestore(); }); });
验证逻辑
修正后,useEffect里的异步函数可以正常拿到权限返回结果,执行setHasPermission触发组件重渲染,此时生成的快照就是hasPermission = true对应的渲染结果,符合测试预期。
内容的提问来源于stack exchange,提问作者Ian Dershem
相关产品推荐
相关产品推荐

