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

Jest Mock测试React组件时findAllByRole返回空的问题求助

问题解决:React测试中findAllByRole找不到listitem元素

核心问题分析

你的代码存在4个关键错误,导致测试失败:

  • Mock配置时机滞后:组件在beforeEach中提前渲染,此时axios的mock尚未配置,组件内的useEffect调用getItems时拿到的是无效响应
  • 异步查询未等待:findAllByRole是异步方法,未用await会返回Promise对象,无法正确断言长度
  • JSX渲染语法错误:items.map未包裹在JSX大括号中,且缺少return逻辑,列表项根本没有被渲染
  • 冗余调用无意义:测试中手动调用await getItems()不会触发组件的state更新,完全无效

修改后的代码

1. MainSection.test.js

import React from 'react';
import { render, screen } from '@testing-library/react';
import MainSection from './MainSection.js';
import axios from 'axios';
import mockProducts from '../../Database/mockProducts.js';

jest.mock('axios');

beforeEach(() => {
    // 先配置mock,再渲染组件
    axios.get.mockResolvedValue({
        data: mockProducts,
    });
    render(<MainSection />);
});

test('Check if renders all the 20 items in the MainSection', async () => {
    // 等待异步渲染完成,获取listitem元素
    const allBoxes = await screen.findAllByRole('listitem');
    expect(allBoxes).toHaveLength(20);
});

2. MainSection.js

修复map的JSX语法错误:

import React, { useState, useEffect } from 'react';
import SearchBar from './SearchBar/SearchBar.js';
import FiltersBox from './FiltersBox/FiltersBox.js';
import { getItems } from '../../Database/Database.js';
import './MainSection.css';

function MainSection() {
    const [items, setItems] = useState([]);

    useEffect(() => {
        getItems().then(res => setItems(res));
    }, []);

    return (
        <section>
            <article className='items_container-main'>
                <div className='items_container' role='list'>
                    {/* 修复:添加大括号包裹JS逻辑,补充箭头函数简写的渲染逻辑 */}
                    {items.map(item => (
                        <div
                            className='item_box'
                            style={{ backgroundImage: `url(${item.image})` }}
                            key={item.id}
                            role='listitem'>
                            <div className='item_box-data_container'>
                                <div className='item_box-data_container-price_star'>
                                    <div className='item_box-price'>${item.price}</div>
                                    <div className='item_box-title'>{item.title}</div>
                                </div>
                            </div>
                        </div>
                    ))}
                </div>
            </article>
        </section>
    );
}

export default MainSection;

额外说明

  • 确保mockProducts的实际长度和断言的20一致,否则需要调整数字
  • 若需要更强的稳定性,可改用waitFor包裹断言:
    await waitFor(() => {
        expect(screen.getAllByRole('listitem')).toHaveLength(20);
    });
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 19:48:17