React Native Testing Library fireEvent.press触发失效如何解决?
问题原因
你测试用例中定义的onSelectLanguage mock函数和WelcomeScreen组件内部声明的onSelectLanguage是完全独立的两个变量,你没有将mock函数传递给组件,组件点击时触发的是自身内部的原始方法,所以mock函数不会产生调用记录,这是报错的核心原因。
解决方案
建议优先通过验证函数执行后的副作用来测试逻辑,不需要额外mock组件内部方法,修改步骤如下:
- 先在测试文件顶部mock相关依赖
// 替换为你项目中i18n的实际引入路径 jest.mock('i18next', () => ({ changeLanguage: jest.fn() })) // 替换为saveData、APP_LANG的实际模块路径 jest.mock('../src/utils/storage', () => ({ saveData: jest.fn(), APP_LANG: 'APP_LANG' }))
- 修改测试用例的断言逻辑
import React from 'react'; import {Provider} from 'react-redux'; import ConfigureStore from '../src/redux/store'; import WelcomeScreen from '../src/screens/auth/WelcomeScreen'; import {ThemeContextProvider} from '../src/themes/themeProvider'; import {fireEvent, render} from '@testing-library/react-native'; import i18n from 'i18next'; // 替换为实际路径 import {saveData, APP_LANG} from '../src/utils/storage'; const store = ConfigureStore(); jest.useFakeTimers(); describe('Welcome Screen tests', () => { const navigation = { navigate: jest.fn(), }; it('select english language', () => { const {getByTestId} = render( <Provider store={store}> <ThemeContextProvider> <WelcomeScreen navigation={navigation} /> </ThemeContextProvider> </Provider>, ); const button = getByTestId('selectEngButton'); fireEvent.press(button); // 断言副作用执行符合预期 expect(i18n.changeLanguage).toHaveBeenCalledWith('en'); expect(saveData).toHaveBeenCalledWith(APP_LANG, 'en'); }); });
可选方案(如果需要直接mock内部方法)
如果确实需要直接监听onSelectLanguage的调用,可以将该方法从组件内部抽离为props参数,测试时将mock函数作为props传入组件即可:
// WelcomeScreen.js 调整为接收可选的onSelectLanguage prop const WelcomeScreen = ({ navigation, onSelectLanguage: propOnSelectLanguage }) => { const onSelectLanguage = propOnSelectLanguage || ((lang) => { setActiveLanguage(lang); i18n.changeLanguage(lang); saveData(APP_LANG, lang); }) // 剩余组件逻辑不变 }
测试时传入mock函数:
const onSelectLanguage = jest.fn(); render( <Provider store={store}> <ThemeContextProvider> <WelcomeScreen navigation={navigation} onSelectLanguage={onSelectLanguage} /> </ThemeContextProvider> </Provider> ); fireEvent.press(button); expect(onSelectLanguage).toHaveBeenCalledWith('en');
内容的提问来源于stack exchange,提问作者Muhammad Afaq Raiz
相关产品推荐
相关产品推荐

