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

在jest 0.29中获取RN组件SplashScreen的generatePrivateKey方法实例

解决方案

针对React Native 0.70的SplashScreen组件在Jest 29中的测试问题,以下是两种可行的处理方式:

一、推荐:模拟用户交互测试(符合Testing Library理念)

Testing Library的核心是模拟真实用户操作,而非直接调用组件内部方法,这种方式更贴近实际场景,也避免耦合组件内部实现。

步骤说明:

  1. 修正navigation参数:原代码中传入的是返回navigation对象的函数,组件实际需要直接的navigation对象,需调整。
  2. 定位触发按钮:通过按钮的title属性找到"生成(新)密钥"按钮。
  3. 模拟点击并验证:触发点击事件后,验证方法调用或执行后的状态变化。

示例代码:

import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { render, screen, fireEvent, waitFor } from "@testing-library/react-native";
import SplashScreen from './SplashScreen';

// 监控组件内部方法,通过mock组件实现
jest.mock('./SplashScreen', () => {
  const OriginalSplashScreen = jest.requireActual('./SplashScreen').default;
  return {
    default: jest.fn((props) => {
      const component = OriginalSplashScreen(props);
      // 为可访问的内部方法添加spy
      if (component.generatePrivatekey) {
        component.generatePrivatekey = jest.fn(component.generatePrivatekey);
      }
      return component;
    })
  };
});

describe('Splash screen when launching the app', () => {
  test('generate private key method shall work', async () => {
    // 修正navigation为直接对象
    const navigation = { navigate: jest.fn() };

    render(
      <NavigationContainer>
        <SplashScreen navigation={navigation} />
      </NavigationContainer>
    );

    // 定位触发按钮
    const generateBtn = screen.getByTitle('生成(新)密钥');
    // 模拟用户点击
    fireEvent.press(generateBtn);

    // 验证方法被调用一次
    await waitFor(() => {
      expect(SplashScreen.mock.results[0].value.generatePrivatekey).toHaveBeenCalledTimes(1);
    });

    // 也可验证状态变化,比如按钮切换为"保存"
    // await waitFor(() => {
    //   expect(screen.getByTitle('保存')).toBeTruthy();
    // });
  });
});

二、获取组件实例直接调用方法(不推荐,耦合内部实现)

如果确实需要直接访问组件内部方法,需根据组件类型做不同处理:

1. 类组件场景

类组件可通过测试实例直接获取组件对象,进而spy或调用方法:

import React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { render, screen, fireEvent } from "@testing-library/react-native";
import SplashScreen from './SplashScreen';

describe('Splash screen when launching the app', () => {
  test('generate private key method shall work', () => {
    const navigation = { navigate: jest.fn() };
    const wrapper = render(
      <NavigationContainer>
        <SplashScreen navigation={navigation} />
      </NavigationContainer>
    );

    // 获取组件实例
    const splashInstance = wrapper.getByType(SplashScreen).instance;
    // Spy内部方法
    const generateSpy = jest.spyOn(splashInstance, 'generatePrivatekey');

    // 模拟点击触发方法
    fireEvent.press(screen.getByTitle('生成(新)密钥'));

    expect(generateSpy).toHaveBeenCalledOnce();
  });
});

2. 函数组件场景

函数组件没有实例,需通过forwardRef + useImperativeHandle暴露内部方法:

第一步:修改SplashScreen组件

import { forwardRef, useImperativeHandle } from 'react';

const SplashScreen = forwardRef((props, ref) => {
  const generatePrivatekey = () => {
    // 原方法逻辑
  };

  // 暴露方法给外部ref
  useImperativeHandle(ref, () => ({
    generatePrivatekey
  }));

  // 原组件视图内容不变
  return (
    // ...你的组件视图代码
  );
});

export default SplashScreen;

第二步:测试代码中获取ref并验证

import React, { useRef } from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { render, screen, fireEvent, waitFor } from "@testing-library/react-native";
import SplashScreen from './SplashScreen';

describe('Splash screen when launching the app', () => {
  test('generate private key method shall work', async () => {
    const navigation = { navigate: jest.fn() };
    const splashRef = useRef(null);

    render(
      <NavigationContainer>
        <SplashScreen navigation={navigation} ref={splashRef} />
      </NavigationContainer>
    );

    // Spy暴露的方法
    const generateSpy = jest.spyOn(splashRef.current, 'generatePrivatekey');
    // 模拟点击触发方法
    fireEvent.press(screen.getByTitle('生成(新)密钥'));

    await waitFor(() => {
      expect(generateSpy).toHaveBeenCalledOnce();
    });
  });
});

内容的提问来源于stack exchange,提问作者user938363

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 08:01:32