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

Expo/React Native Testing Library无法找到testID问题求助

问题:测试时无法找到自定义Text组件的testID元素

使用Expo和React Native Testing Library测试Landing页面时,无法定位到testID为landing-title的元素,报错提示无法找到该元素。


相关代码片段

Text.tsx

import {
  TextProps as Props,
  StyleSheet,
  Text as SystemText,
} from 'react-native';

import useIsDarkMode from '@hooks/utils/useIsDarkMode';

import { theme } from '@theme/theme';

interface TextProps extends Props {
  text: string;
}

const Text = ({ text, style, ...rest }: TextProps) => {
  const isDarkMode = useIsDarkMode();

  return (
    <SystemText
      style={[
        {
          color: isDarkMode ? theme.colors.white : theme.colors.black,
          ...styles.text,
        },
        style,
      ]}
      allowFontScaling={false}
      {...rest}
    >
      {text}
    </SystemText>
  );
};

export default Text;

const styles = StyleSheet.create({
  text: {
    includeFontPadding: false,
    fontSize: theme.fontSizes.sm,
    fontFamily: theme.fontFamily.regular,
  },
});

Landing.tsx

const Landing = () => {
  const navigation = useAppNavigation<'AuthStack'>();
  const { triggerHaptic } = useHaptics();

  const navigateToEnterEmail = () => {
    triggerHaptic();
    navigation.navigate('EnterEmail');
  };

  return (
    <SafeViewContainer>
      <View style={styles.mainView}>
        <View style={styles.headingView}>
          <Text text="My title" style={styles.title} testID="landing-title" />
          <Text
            text="My subtitle"
            style={styles.subtitle}
            testID="landing-subtitle"
          />
        </View>
        <View>
          <PrimaryButton
            text="Get started"
            style={styles.text}
            onPress={navigateToEnterEmail}
            testID="get-started-button"
          />
        </View>
      </View>
    </SafeViewContainer>
  );
};

Landing.test.tsx

import { NavigationContainer } from '@react-navigation/native';
import { render, screen } from '@testing-library/react-native';
import { SafeAreaProvider } from 'react-native-safe-area-context';

import Landing from '@screens/AuthScreens/Landing';

describe('Landing', () => {
  it('renders the proper title and subtitle', async () => {
    const landingScreen = (
      <SafeAreaProvider>
        <NavigationContainer>
          <Landing />
        </NavigationContainer>
      </SafeAreaProvider>
    );

    render(landingScreen);

    const landingTitle = await screen.getByTestId('landing-title');

    expect(landingTitle).toHaveTextContent('My title');
  });
});

报错信息

Landing › renders the proper title and subtitle

    Unable to find an element with testID: landing-title

      17 |     render(landingScreen);
      18 |
    > 19 |     const landingTitle = await screen.getByTestId('landing-title');
         |                                       ^
      20 |
      21 |     expect(landingTitle).toHaveTextContent('My title');
      22 |   });

依赖版本

"@testing-library/jest-dom": "^5.16.5",
    "@types/jest": "^29.4.0",
    "jest": "^29.2.1",
    "jest-expo": "^48.0.1",
    "@testing-library/react-native": "^12.0.0-rc.0",

排查与解决方案

1. Mock未实现的自定义钩子

自定义Text组件依赖useIsDarkMode钩子,测试环境没有该钩子的运行上下文,需手动模拟其返回值:

// 在Landing.test.tsx顶部添加
jest.mock('@hooks/utils/useIsDarkMode', () => ({
  __esModule: true,
  default: () => false, // 模拟浅色模式,可根据需求改为true
}));

2. 移除不必要的await

getByTestId是同步查询方法,不需要使用await,多余的异步等待会导致测试逻辑异常:

// 原代码
const landingTitle = await screen.getByTestId('landing-title');

// 修改后
const landingTitle = screen.getByTestId('landing-title');

3. 确保主题模块可被测试环境访问

若theme对象在测试环境中无法正确加载,会导致样式解析错误,使组件不可见。可mock主题模块:

// 在Landing.test.tsx顶部添加
jest.mock('@theme/theme', () => ({
  theme: {
    colors: {
      white: '#ffffff',
      black: '#000000',
    },
    fontSizes: {
      sm: 14,
    },
    fontFamily: {
      regular: 'Arial',
    },
  },
}));

4. 检查自定义容器组件的渲染

如果SafeViewContainer是自定义组件,需确保它在测试环境中正确渲染子元素,必要时mock该组件:

// 在Landing.test.tsx顶部添加
jest.mock('@components/SafeViewContainer', () => ({
  __esModule: true,
  default: ({ children }) => <>{children}</>,
}));

5. 使用debug工具排查渲染结构

在render后添加screen.debug(),打印当前渲染的DOM结构,确认组件是否被正确渲染:

render(landingScreen);
screen.debug(); // 查看输出结构,确认Text组件是否存在

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 10:32:09