React测试遇TypeError: Cannot read properties of undefined(reading 'includes')问题求助
问题
运行React测试时遭遇TypeError: Cannot read properties of undefined (reading 'includes')错误,测试卡在第26行。注释该行后测试能正常返回预期结果,保留则触发错误。调试发现contentType的值为undefined,但不知道如何在测试中处理这种情况。
完整错误信息:
● display data › should render data TypeError: Cannot read properties of undefined (reading 'includes') 24 | const lastIndex = currentPage * productsPerPage; 25 | const firstIndex = lastIndex - productsPerPage; > 26 | const productsByContentType = products.filter((type: Products) => type.contentType.includes(contentTypeValue)) || products; | ^ 27 | const filteredProducts = sortBy?.[filterValue]?.(productsByContentType) ?? productsByContentType; 28 | 29 | const productsBySearchValue = filteredProducts.filter((search: Products) => {
测试代码:
describe('display data', () => { afterEach(() => { jest.restoreAllMocks(); }); test('should render data', async () => { const mAxiosResponse = { data: [{title: "5-Minute Stories: In the Wild"}], } as AxiosResponse; jest.spyOn(axios, 'get').mockResolvedValueOnce(mAxiosResponse); render(<Landing />); expect(screen.getByText('Loading...')).toBeInTheDocument(); expect(await screen.findByDisplayValue('Name:')).toBeInTheDocument(); }); });
组件核心代码:
function App() { const [products, setProducts] = useState<Products[]>([]); const [contentTypeValue, setContentTypeValue] = useState<string>('Stories'); // ...其他状态定义 const productsByContentType = products.filter((type: Products) => type.contentType.includes(contentTypeValue)) || products; // ...其他过滤、排序逻辑 const fetchData = async () => { axios.get('http://localhost:3030/products') .then((res: AxiosResponse<Products[]>) => { setProducts(res.data); }) .catch((err) => console.log(err)) }; useEffect(() => { fetchData() setSearchValue(''); }, []); // ...其他渲染逻辑 }
解决方案
1. 修复组件空值安全问题
错误根源是type.contentType可能为undefined,调用includes前必须先做空值校验。修改第26行的过滤逻辑:
const productsByContentType = products.filter((type: Products) => type.contentType?.includes(contentTypeValue) ?? false ) || products;
使用可选链?.规避contentType为undefined的情况,再通过?? false确保空值时返回false,不会触发过滤。
同时建议同步修复搜索逻辑中的同类问题:
const productsBySearchValue = filteredProducts.filter((search: Products) => { return search.title?.toLowerCase().includes(searchValue) ?? false; }) || filteredProducts;
2. 完善测试Mock数据
测试返回的Mock数据缺少contentType字段,导致组件处理时出现undefined。更新测试的响应数据:
const mAxiosResponse = { data: [{ title: "5-Minute Stories: In the Wild", contentType: "Stories", // 补充必填的contentType字段 id: 1, price: 9.99, productType: "Book", imgSet: { sm: { src: "test-image.jpg" } } }], } as AxiosResponse;
补充Products类型要求的完整字段,确保组件能正常处理数据,避免因字段缺失引发错误。
3. 新增边界场景测试
可以添加测试用例,验证组件在contentType为undefined时的稳定性:
test('should handle products with undefined contentType', async () => { const mAxiosResponse = { data: [ {title: "Test Product", contentType: undefined, id: 2, price: 19.99, productType: "E-book", imgSet: { sm: { src: "test.jpg" } }}, {title: "Story Product", contentType: "Stories", id: 3, price: 12.99, productType: "Book", imgSet: { sm: { src: "test2.jpg" } }} ], } as AxiosResponse; jest.spyOn(axios, 'get').mockResolvedValueOnce(mAxiosResponse); render(<Landing />); // 验证组件正常渲染无崩溃 expect(await screen.findByText('Name: Test Product')).toBeInTheDocument(); });
内容的提问来源于stack exchange,提问作者RogerBanks
相关产品推荐
相关产品推荐

