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

如何在Jest中测试React Native DateTimePicker的日期选择与标签更新?

解决React Native DateTimePicker的Jest测试问题

问题描述

我制作了一个简化版React Native项目,包含一个按钮,点击后会打开Date Picker。用户选择日期后,文本标签会更新,datePicker的onChange函数会调用另一个函数。尝试在Jest测试套件中与datePicker交互(更改其值并测试标签是否更新)时,出现错误Unable to find an element with testID: dateTimePicker。

项目代码

import React from 'react';
import { useState } from "react"
import { Platform, Button, Text, View} from 'react-native';
import DateTimePicker from '@react-native-community/datetimepicker';

const App = () => {
  const [date, setDate] = useState(new Date());
  const [mode, setMode] = useState('date');
  const [show, setShow] = useState(false);

  const onChange = (event, selectedDate) => {
    const currentDate = selectedDate;
    setShow(false);
    setDate(currentDate);
    testFunction()
  };

  const showMode = (currentMode) => {
    if (Platform.OS === 'android') {
      setShow(true);
    }
    setMode(currentMode);
  };

  const showDatepicker = () => {
    showMode(mode);
  };

  function testFunction(){
    console.log("testFunction called")
  }

  return (
    <View style={{
        flex: 1,
        justifyContent: "center",
        alignItems: "center"
      }}>
      <Button style={{margin:50}} onPress={showDatepicker} title="Show date picker!" />
      <Text>selected: {date.toLocaleString()}</Text>
      {show && (
        <DateTimePicker
          testID="dateTimePicker"
          value={date}
          mode={mode}
          is24Hour={true}
          onChange={onChange}
        />
      )}
    </View>
  );
};

export default App;

测试代码(原错误版本)

import React from 'react';
import renderer from 'react-test-renderer';
import {fireEvent, render, screen, waitFor, userEvent} from '@testing-library/react-native';

import App from "../app"

jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper')

describe('Date Picker Tests', () => {
    it.only("changing the date of datepicker", async() => {
    let journal = render(<App/>)
    let text = screen.getByText("Show date picker!")
    fireEvent.press(text)
    let p = screen.getByTestId("dateTimePicker")
    console.log(p)
    })
})

解决方案

1. 解决testID找不到的问题

原错误原因:测试环境默认Platform.OS为iOS,而组件中仅在Android平台下才会设置show = true,导致DateTimePicker未渲染。

解决方式:在测试中模拟Platform.OS为Android,确保点击按钮后Picker能正常渲染:

jest.mock('react-native/Libraries/Utilities/Platform', () => ({
  OS: 'android',
  select: jest.fn(),
}));

2. 完整测试代码(验证日期更新与函数调用)

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

// 模拟Android平台,确保Picker渲染
jest.mock('react-native/Libraries/Utilities/Platform', () => ({
  OS: 'android',
  select: jest.fn(),
}));

// Mock testFunction,验证是否被调用
jest.mock('../app', () => {
  const originalModule = jest.requireActual('../app');
  return {
    __esModule: true,
    ...originalModule,
    testFunction: jest.fn(),
  };
});

describe('Date Picker Tests', () => {
  it('updates selected date text and calls testFunction on date change', async () => {
    render(<App />);
    
    // 点击按钮打开Picker
    const showButton = screen.getByText("Show date picker!");
    fireEvent.press(showButton);
    
    // 确认Picker已渲染
    const datePicker = screen.getByTestId("dateTimePicker");
    
    // 模拟选择一个新日期
    const newDate = new Date('2024-01-01');
    fireEvent.change(datePicker, { nativeEvent: { selectedDate: newDate } });
    
    // 验证文本标签是否更新为新日期
    await waitFor(() => {
      expect(screen.getByText(`selected: ${newDate.toLocaleString()}`)).toBeTruthy();
    });
    
    // 验证testFunction是否被调用
    const { testFunction } = require('../app');
    expect(testFunction).toHaveBeenCalledTimes(1);
  });
});

关键说明

  • 模拟平台:通过jest.mock强制测试环境为Android,确保Picker渲染。
  • Mock函数:对testFunction进行Mock,方便验证日期选择后该函数是否被正确调用。
  • 触发Change事件:使用fireEvent.change模拟用户选择日期的行为,传入自定义的新日期。
  • 等待异步更新:使用waitFor等待组件状态更新后再验证文本内容,避免测试因状态未同步而失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 08:50:24