如何在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
相关产品推荐
相关产品推荐

