Jest与Enzyme测试中出现Cannot read property includes of undefined错误求助
解决React组件测试中"Cannot read property 'includes' of undefined"错误
问题根源
我一眼就发现问题所在啦!你的测试用例里传入的appliedFilterList是一个数组,但组件的generateCheckboxes函数明确期望它是一个对象!
看你定义的测试数据:
const appliedFilters = [ { access: ["Access Type Of The Service"], bandwidth: ["the allowed band width", "the allowed band width"], term: ["term associated with the service"] } ];
这里appliedFilters被包裹在数组里,但组件里是直接用props.appliedFilterList[filterType]来访问对应类型的过滤数组的。当你把数组传给appliedFilterList时,appliedFilterList["access"]会返回undefined(因为数组只能用数字索引,字符串索引无法匹配数组元素里的对象属性),调用includes自然就抛出类型错误了。
另外还有个小坑:你给toggleFilter传的是false,但组件里是把它当作函数来调用的(onClick={() => props.toggleFilter(filterType, filter)}),后续如果做点击测试也会报错,得改成模拟函数才行。
修复步骤
- 修正
appliedFilters的结构,去掉外层数组,直接用对象:
const appliedFilters = { access: ["Access Type Of The Service"], bandwidth: ["the allowed band width", "the allowed band width"], term: ["term associated with the service"] };
- 把
toggleFilter换成模拟函数,比如用Jest的jest.fn():
const wrapper = mount( <FilterDropdownContent accessFilters={accessData} bandwidthFilters={bandwidthData} appliedFilterList={appliedFilters} termsFilters={termsFiltersData} toggleFilter={jest.fn()} /> );
- 可选:给组件加边界保护,避免未来再出现类似问题。在
generateCheckboxes里,先判断props.appliedFilterList[filterType]是否存在,不存在就用空数组兜底:
const generateCheckboxes = (array, filterType) => { return array.map((filter, i) => { if (!isNullOrUndefined(filter) && filter !== "") { // 加默认值,防止appliedFilterList[filterType]不存在 const appliedFilters = props.appliedFilterList[filterType] || []; const applied = appliedFilters.includes(filter); console.log("yes", appliedFilters); return ( <Row key={i} noLine={i === 0}> <Checkbox checked={applied} onClick={() => props.toggleFilter(filterType, filter)}> {filter} </Checkbox> </Row> ); } return false; }); };
验证测试
修改完之后,再运行测试,应该就能正常渲染,不会再抛出includes的错误了。你还可以加一些断言,验证Checkbox的选中状态是否符合预期:
it("renders correctly and checks applied filters", () => { const wrapper = mount( <FilterDropdownContent accessFilters={accessData} bandwidthFilters={bandwidthData} appliedFilterList={appliedFilters} termsFilters={termsFiltersData} toggleFilter={jest.fn()} /> ); // 验证第一个Access的Checkbox是选中状态 expect(wrapper.find(Checkbox).first().props().checked).toBe(true); });
内容的提问来源于stack exchange,提问作者pranami
相关产品推荐
相关产品推荐

