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

如何编写StencilJS组件成功销毁场景的单元测试用例

StencilJS 组件销毁场景单元测试实现方案

Stencil 的 SpecPage 提供了完整的DOM模拟和生命周期触发能力,组件销毁测试可以直接复用现有渲染用例的初始化逻辑,核心通过移除DOM节点触发组件销毁流程,再从DOM残留、生命周期触发、副作用清理三个维度做断言即可。

核心验证维度

  • 组件从DOM树移除后,无残留DOM节点,shadowRoot渲染内容被正常清理
  • 组件disconnectedCallback销毁生命周期钩子按预期触发
  • 组件内部注册的全局事件、定时器、第三方实例(如图表、表格实例)等副作用被正确回收,无内存泄漏隐患

基础用例实现(验证DOM销毁逻辑)

it('destroy component-name component correctly', async () => {
  // 复用渲染用例的初始化逻辑
  const page = await newSpecPage({
    components: [componentName],
    html: `<component-name model-id="${Model.id}"></component-name>`,
  });
  page.rootInstance.Data = {
    Model: [Model],
    Value: [Value],
    Status: []
  }
  page.rootInstance.tableModel = tableModel;
  page.rootInstance.tableValues = tableValues;
  await page.waitForChanges();

  // 前置校验:确认组件已正常渲染,避免初始化失败导致销毁用例误判
  const chartBeforeDestroy = page.root.shadowRoot.querySelector('component-html');
  expect(chartBeforeDestroy.innerHTML).not.toBeNull();

  // 触发销毁:从DOM树移除组件根节点
  page.root.remove();
  await page.waitForChanges();

  // 销毁结果断言
  expect(document.body.querySelector('component-name')).toBeNull();
  expect(page.root.isConnected).toBe(false);
});

进阶校验(生命周期与副作用清理)

如果需要覆盖更完整的销毁逻辑,可以补充以下断言:

  • 校验销毁生命周期钩子触发:
// 组件渲染完成后、执行移除前,注入生命周期监听
const disconnectSpy = jest.spyOn(page.rootInstance, 'disconnectedCallback');

// 执行移除、等待变更检测后断言
expect(disconnectSpy).toHaveBeenCalledTimes(1);
  • 校验内部实例/副作用清理:
    如果组件内部维护了图表、表格这类第三方实例,或者注册了全局事件、定时器,可以通过spy监听对应销毁方法的调用:
// 示例:监听内部图表实例的销毁方法
const chartDestroySpy = jest.spyOn(page.rootInstance.chart, 'destroy');
// 移除组件后断言销毁方法被调用
expect(chartDestroySpy).toHaveBeenCalledTimes(1);

注意:所有DOM操作、断言执行前必须调用await page.waitForChanges(),等待Stencil完成异步渲染和生命周期调度,避免时序问题导致用例偶现失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 23:24:14