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

使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 02:54:03