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

测试依赖自定义useFetch Hook的React组件渲染失败问题

问题:测试AgentsContainer组件时无法找到agent-card元素

我在测试依赖自定义useFetch Hook的AgentsContainer组件,验证它是否能正确渲染所有Agent卡片,但测试时出现无法找到data-testid='agent-card'元素的错误。另外,移除agents后的可选链操作符(?)会抛出"TypeError: Cannot read properties of undefined (reading 'map')"错误。


AgentsContainer.js

import React from 'react';
import { useFetch } from '../../hooks/useFetch.js';
import AgentBox from './AgentBox/AgentBox.js';

function AgentsContainer() {
    const { agents, loading, error } = useFetch(
        'https://valorant-api.com/v1/agents'
    );

    return (
        <section>
            <div>
                {error && <div>Error: {error.message}</div>}

                {loading && <div>Loading...</div>}

                {agents?.map(agent => {
                    return (
                        agent.isPlayableCharacter && (
                            <AgentBox key={agent.uuid} data-testid='agent-card' {...agent} />
                        )
                    );
                })}
            </div>
        </section>
    );
}

export default AgentsContainer;

useFetch.js

import { useState, useEffect } from 'react';
import axios from 'axios';

export function useFetch(url) {
    const [agents, setAgents] = useState([]);
    const [loading, setLoading] = useState(true);
    const [error, setError] = useState();

    useEffect(() => {
        setLoading(true);

        axios
            .get(url)
            .then(({ data: { data } }) => {
                setAgents(data);
            })
            .catch(error => setError(error))
            .finally(() => setLoading(false));
    }, []);

    return { agents, loading, error };
}

AgentsContainer.test.js

import React from 'react';
import { render, screen } from '@testing-library/react';
import AgentsContainer from './AgentsContainer.js';
import agentsMock from '../../mock/mock.js';
import axios from 'axios';

jest.mock('axios');

test('Renders Agents cards', async () => {
    axios.get.mockResolvedValue({
        data: agentsMock,
        loading: true,
        error: 'Something went wrong D:'
    });

    render(<AgentsContainer />);

    const agentsCards = await screen.findAllByTestId('agent-card');

    expect(agentsCards).toHaveLength(3);
});

控制台报错信息

Unable to find an element by: [data-testid="agent-card"]

    Ignored nodes: comments, script, style
    <body>
      <div>
        <section>
          <div />
        </section>
      </div>
    </body>

      16 |      render(<AgentsContainer />);
      17 |
    > 18 |      const agentsCards = await screen.findAllByTestId('agent-card');
         |                                       ^
      19 |
      20 |      expect(agentsCards).toHaveLength(3);
      21 | });

注:测试中导入的agentsMock是包含3个对象的数组,数据量较大未贴出,需要可提供。


解决方案

1. 修复Axios Mock的返回结构

useFetch中对Axios响应的处理是({ data: { data } }),意味着它期望响应结构为{ data: { data: 代理数组 } },但当前测试的mock直接返回了{ data: agentsMock },导致setAgents(data)接收到的内容不符合预期,无法生成Agent卡片。

修正后的mock代码:

axios.get.mockResolvedValue({
    data: {
        data: agentsMock // 匹配useFetch的解构层级
    }
});

2. 确保Mock数据满足渲染条件

AgentsContainer仅在agent.isPlayableCharacter为true时才渲染AgentBox,因此agentsMock中的每个对象必须包含isPlayableCharacter: true字段,否则不会生成对应的卡片元素。

3. 修正可选链报错问题

移除agents?.map的可选链后报错,本质是mock结构错误导致agents被设置为undefined。修复mock结构后,useFetch初始的agents状态为数组,不会出现读取map的报错。

修正后的完整测试代码

import React from 'react';
import { render, screen } from '@testing-library/react';
import AgentsContainer from './AgentsContainer.js';
import agentsMock from '../../mock/mock.js';
import axios from 'axios';

jest.mock('axios');

test('Renders Agents cards', async () => {
    axios.get.mockResolvedValue({
        data: {
            data: agentsMock
        }
    });

    render(<AgentsContainer />);

    // 可额外验证loading状态的切换
    await screen.findByText(/Loading.../i);
    const agentsCards = await screen.findAllByTestId('agent-card');

    expect(agentsCards).toHaveLength(3);
});

额外检查点

  • 确认AgentBox组件正确接收并保留了data-testid属性,未被内部逻辑覆盖或丢失
  • 检查agentsMock中的每个对象是否包含uuid(作为React元素的key)和isPlayableCharacter: true字段

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 11:17:40