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

如何使用Jest测试无框架纯JS Web Components中的slotted插槽元素

问题原因

  1. 原组件中直接读取<slot>元素的innerText属于依赖浏览器渲染特性的非标准写法:插槽元素本身的DOM结构是空的,浏览器渲染阶段会将宿主下分配给插槽的节点渲染到插槽对应位置,因此浏览器中可读取到innerText,但Jest默认使用的jsdom环境没有实现这类渲染层的文本计算逻辑,因此返回undefined。
  2. 测试中创建的自定义元素没有挂载到document上,jsdom不会触发插槽分配逻辑,导致插槽无法识别到传入的文本节点。

解决方案

第一步:修正组件的name getter,使用标准插槽API读取内容

替换原有的name getter为调用插槽标准assignedNodes()方法的实现,直接读取分配给插槽的节点内容,不依赖渲染层特性:

// placeholder.js 修正后的name getter
get name() {
    const slot = this.shadowRoot.querySelector("slot");
    // 读取所有分配给插槽的节点的文本内容并拼接
    return slot.assignedNodes().map(node => node.textContent).join('');
}

第二步:修正测试用例,触发插槽分配

测试中需要将创建的自定义元素挂载到document上,触发jsdom的插槽分配逻辑,同时增加用例执行后的DOM清理逻辑避免测试污染:

// placeholder.test.js 修正后代码
import Placeholder from "../src/placeholder.js";

describe("name is 'Lorem Ipsum'", () => {
    let ph;
    
    beforeEach(() => {
        ph = new Placeholder();
        const textNode = document.createTextNode("Lorem Ipsum");
        ph.appendChild(textNode);
        // 将组件挂载到document,触发插槽分配
        document.body.appendChild(ph);
    });

    afterEach(() => {
        // 测试结束后清理DOM
        ph.remove();
    });

    test("if the name is 'Lorem Ipsum'", () => {
        expect(ph.name).toBe("Lorem Ipsum");
    });
});

可选:补充Jest配置适配自定义元素

如果修改后仍报错,可在jest配置文件中增加jsdom的自定义元素支持配置:

// jest.config.js
module.exports = {
    testEnvironment: "jsdom",
    testEnvironmentOptions: {
        customExportConditions: ["node", "custom"],
        runScripts: "dangerously"
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 02:24:03