为何Jest测试因缺少唯一key属性而失败?
React列表key警告导致Jest测试失败
多个测试因以下错误失败:
Warning: Each child in a list should have a unique "key" prop.%s%s
我了解React的key属性要求,已经为<li />元素添加了key,但问题仍未解决:
Error: Warning: Each child in a list should have a unique "key" prop
(明明已经给列表项加了key,怎么还报这个错?)
于是我尝试给所有HTML元素都添加key,最终代码如下:
import React, { Component } from 'react'; import { constants, ProductStatusInfo, Tooltip } from 'trucktrax-common'; import { AGGREGATE_STRING, CEMENT_STRING, READYMIX_VALUE } from '../../../constants/appConstants'; import styles from './LegendMapKey.module.scss'; export class LegendMapKey extends Component<LegendMapKeyProps> { bySequenceNumber = (a: ProductStatusInfo, b: ProductStatusInfo) => a.sequenceNumber - b.sequenceNumber; productStatusInfoToListItem = (psi: ProductStatusInfo, index: number): JSX.Element => this.renderListItem(psi, index); productStatusInfosToListItems = (psiList: ProductStatusInfo[]) => Object.values(psiList) .sort(this.bySequenceNumber) // musn't forget to sort them // this list is static, and will not change, so using an index is fine .map(this.productStatusInfoToListItem); renderListItem = (psi: ProductStatusInfo, key: number) => ( // what a very nice key for every list item <li key={key} className={styles.statusKey}> <Tooltip key={`tt${key}`} theme="info" text={psi.name} classes={{ popper: styles.popper, tooltip: styles.tooltip }} > <span key={`span${key}`}> <i key={`dot${key}`} className="icon-dot" style={{ color: psi.color }} /> {psi.abbreviation} </span> </Tooltip> </li> ) renderProductStatusList = (key: string, title: string, psiList: ProductStatusInfo[]) => { const list = this.productStatusInfosToListItems(psiList); return ( <div key={key} className={styles.productColumn}> <div key={`title${key}`} className={styles.title}>{title}</div> <ul key={`ul${key}`}>{list}</ul> </div> ); }; renderMapStateKeys = () => { const emptyElement = (<></>); const { productLines } = this.props; const { aggregateStatuses, cementStatuses, readyMixStatuses } = constants.PRODUCT_STATUSES; const aggregate = productLines.includes(AGGREGATE_STRING) ? this.renderProductStatusList('LegendAgg', 'Aggr.', aggregateStatuses) : emptyElement; const cement = productLines.includes(CEMENT_STRING) ? this.renderProductStatusList('LegendCement', 'Cement', cementStatuses) : emptyElement; const readyMix = productLines.includes(READYMIX_VALUE) ? this.renderProductStatusList('LegendRMix', 'R.Mix', readyMixStatuses) : emptyElement; // they need to be in this order in the legend return [aggregate, cement, readyMix]; } render() { return ( <div key="legend" className={styles.legend}> {this.renderMapStateKeys()} </div> ); } } export default LegendMapKey; export interface LegendMapKeyProps { productLines: string[]; }
这段代码运行时没有报错,但Jest测试仍然失败,调试时出现如下提示:
console.error src/setupTests.ts:25
Check the top-level render call using.
in Fragment
示例失败测试用例:
it('should render with Aggregates Only', () => { const testProps = { productLines: ['Aggregates'] }; const wrapper2 = shallow(<LegendMapKey {...testProps} />); expect(wrapper2.length) .toEqual(1); });
内容的提问来源于stack exchange,提问作者Scott Baker
相关产品推荐
相关产品推荐

