如何为含navigation.addListener的React Native useEffect编写单元测试
React Native RecipeScreen 单元测试实现
我们可以使用Jest和@testing-library/react-native编写这两个单元测试,核心思路是mock依赖的API函数和导航钩子,模拟不同场景并验证组件渲染结果。
前置准备
确保项目已安装必要测试依赖:
npm install --save-dev jest @testing-library/react-native @testing-library/jest-native
测试代码实现
创建测试文件RecipeScreen.test.js,编写如下逻辑:
import React from 'react'; import { render, waitFor } from '@testing-library/react-native'; import RecipeScreen from './RecipeScreen'; import { useNavigation } from '@react-navigation/native'; import { fetchRecipes } from './your-api-module'; // 替换为实际API模块路径 // Mock导航钩子与API函数 jest.mock('@react-navigation/native', () => ({ useNavigation: jest.fn(), })); jest.mock('./your-api-module', () => ({ fetchRecipes: jest.fn(), })); describe('RecipeScreen', () => { const mockAddListener = jest.fn((event, callback) => { // 模拟触发focus事件回调 if (event === 'focus') callback(); return jest.fn(); // 返回mock的unsubscribe函数 }); beforeEach(() => { // 重置所有mock jest.clearAllMocks(); useNavigation.mockReturnValue({ addListener: mockAddListener }); }); // 测试API调用失败时显示Error组件 it('renders Error component when API call fails', async () => { // Mock API返回错误 fetchRecipes.mockResolvedValue({ error: true }); const { getByTestId } = render(<RecipeScreen />); await waitFor(() => { // 需给Error组件添加testID="error-component" expect(getByTestId('error-component')).toBeTruthy(); }); }); // 测试API调用成功时显示食谱列表 it('renders recipe list when API call succeeds', async () => { // Mock API返回成功的食谱数据 const mockRecipes = [ { id: '1', title: '番茄炒蛋' }, { id: '2', title: '酸辣土豆丝' }, ]; fetchRecipes.mockResolvedValue({ error: false, recipes: mockRecipes }); const { getAllByTestId, queryByTestId } = render(<RecipeScreen />); await waitFor(() => { // 验证Error组件不存在 expect(queryByTestId('error-component')).toBeNull(); // 验证Recipe组件渲染数量匹配(需给Recipe组件添加testID="recipe-item") const recipeItems = getAllByTestId('recipe-item'); expect(recipeItems).toHaveLength(mockRecipes.length); }); }); });
关键说明
- Mock导航逻辑:通过mock
useNavigation的addListener方法,直接触发focus事件回调,模拟屏幕聚焦行为。 - Mock API函数:根据测试场景让
fetchRecipes返回成功/失败的模拟数据,避免实际调用真实API。 - 异步等待:使用
waitFor确保异步的loadRecipes执行完成后再断言,避免测试过早执行导致结果不准确。 - TestID设置:需给
Error和Recipe组件添加testID属性,方便测试时定位元素。
内容的提问来源于stack exchange,提问作者Rupesh Ghosh
相关产品推荐
相关产品推荐

