Svelte组件遍历对象数组时Jest报{#each}仅遍历类数组对象错误
Svelte图文组件测试报错问题解答
1. {#each} only iterates over array-like objects 报错原因
浏览器端正常渲染、测试环境报错,核心原因是测试运行时buttonList的值不是合法的可遍历数组/类数组结构,和遍历逻辑本身无关,常见触发场景:
- 组件未给
buttonList设置默认值:组件内仅声明了export let buttonList: ButtonModel[],没有初始化默认值。如果测试用例渲染组件时未显式传入该prop,Svelte中未赋值的prop默认值为undefined,{#each}遍历undefined就会抛出该错误。 - svelte-i18n 未正确Mock:你传入的按钮label依赖
$_()翻译函数,测试环境如果没有提前初始化i18n配置、Mock翻译store,$_()可能返回非预期值(如undefined、store对象而非字符串),甚至导致整个buttonList解析失败,变成非数组类型。 - Jest 编译配置缺失:如果Jest没有配置Svelte对应的TypeScript预处理器,组件内的TS类型声明、类定义未被正确编译,可能导致prop解析异常,
buttonList拿到的值不符合数组要求。
2. 代码可优化方向
- 给所有prop添加兜底默认值:从根源避免漏传参数导致的渲染/测试报错,例如:
export let imgSrc: string = ''; export let alt: string = ''; export let articleTitle: string = ''; export let articleContent: string = ''; export let buttonList: ButtonModel[] = []; - 替换冗余的Class定义为TypeScript类型:你实际传参时用的是普通对象字面量,没有用到Class的实例方法、继承等特性,完全不需要定义
ButtonModel类,用type/interface声明结构更轻量,也能避免测试环境Class编译异常问题:type ButtonModel = { href: string; label: string; } - 给
{#each}块添加唯一key:Svelte列表渲染推荐给每一项加唯一key,提升Diff更新效率,避免列表动态增删时出现DOM复用错误:
如果后续按钮配置新增唯一id字段,优先用id作为key。{#each buttonList as buttonModel (buttonModel.href + buttonModel.label)} - 补充可访问性属性:装饰性的
<Icon>组件添加aria-hidden="true",避免屏幕阅读器重复朗读无意义内容;外链类型的按钮可以按需添加target="_blank" rel="noopener noreferrer"属性,提升安全性。 - 测试用例解耦无关依赖:单测渲染组件时优先传入固定的mock props,不要直接依赖i18n翻译函数,i18n逻辑单独写用例覆盖,减少无关依赖导致的测试报错。
内容的提问来源于stack exchange,提问作者JdZ
相关产品推荐
相关产品推荐

