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

使用Jest与Enzyme测试待办列表新增功能时遇map未定义错误求助

解决Jest/Enzyme测试待办列表新增功能的问题

首先,咱们先搞定那个Cannot read property 'map' of undefined的错误——这是因为你的ListItems组件直接对props.items调用map,但如果组件初始化时没有收到items属性(比如测试时单独渲染它却没传props),items就是undefined,自然会报错。

第一步:修复ListItems组件的防错处理

给items设置一个默认值,或者在map之前做空值判断,双重保险:

function ListItems(props){
 // 方法1:设置组件默认props,确保items始终是数组
 ListItems.defaultProps = {
   items: []
 };

 const items= props.items;
 // 方法2:用可选链操作符,避免undefined调用map
 const listItems = items?.map(item => {
 return <div className="list" key={item.id}>
 <p>
 <input type="checkbox" onClick={ () => props.handleClickbox(item.id)} />
 <input style={{ color:"white", textDecoration: item.completed ? "line-through":null}} type="text" id={item.id} value={item.task} onChange ={ (e) =>{ props.setUpdate(e.target.value, item.id) } }/>
 <span>
 <FontAwesomeIcon className="faicons" icon='trash' onClick={ () => props.deleteItem(item.id) } />
 </span>
 </p>
 </div>
 })
 return(
 <div>
 <FlipMove duration={500} easing="ease-in-out" >
 {listItems}
 </FlipMove>
 </div>
 )
}

第二步:正确测试新增功能的完整流程

你的测试思路有问题:新增待办是App组件的完整交互流程,需要在App的上下文中模拟输入、提交,然后验证ListItems里是否出现了新项,而不是单独渲染ListItems或者直接查文档。

用Enzyme编写的测试案例

import React from 'react';
import { mount } from 'enzyme';
import App from './App';
import ListItems from './ListItems';

describe('Todo App Add Item Functionality', () => {
  it('should add a new todo item when form is submitted', () => {
    // 用mount而不是shallow,因为需要测试组件间的交互(表单提交→state更新→ListItems渲染)
    const wrapper = mount(<App />);
    
    // 1. 模拟输入框输入内容
    const input = wrapper.find('#toDoInputId');
    input.simulate('change', { target: { value: 'testFirst' } });
    
    // 2. 模拟表单提交,要手动模拟preventDefault避免默认刷新行为
    const form = wrapper.find('#to-do-form');
    form.simulate('submit', { preventDefault: () => {} });
    
    // 3. 验证App的state是否正确更新
    expect(wrapper.state('items')).toContainEqual(expect.objectContaining({
      task: 'testFirst',
      completed: false,
      id: expect.any(Number) // 如果你的id是自动生成的,用这个匹配任意数字/字符串
    }));
    
    // 4. 验证ListItems里是否渲染了新的待办项
    const listItemInputs = wrapper.find('.list input[type="text"]');
    expect(listItemInputs.last().props().value).toBe('testFirst');
  });
});

用React Testing Library编写的测试案例

如果习惯用React Testing Library,代码会更简洁:

import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import App from './App';

test('adds a new todo item successfully', () => {
  render(<App />);
  
  // 找到输入框并输入内容
  const input = screen.getByPlaceholderText('Enter task');
  fireEvent.change(input, { target: { value: 'testFirst' } });
  
  // 找到提交按钮并点击
  const submitBtn = screen.getByText('Add');
  fireEvent.click(submitBtn);
  
  // 验证新项是否出现在页面中
  expect(screen.getByDisplayValue('testFirst')).toBeInTheDocument();
});

你之前测试失败的核心原因

  1. 单独渲染ListItems却没传items props,直接触发了map的错误;
  2. 没有在App的上下文中模拟完整的「输入→提交」流程,导致测试环境里根本没有渲染出更新后的待办项;
  3. 用shallow渲染App无法捕获子组件的状态更新,建议用mount(Enzyme)或React Testing Library的render。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 12:12:28