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

SolidJS使用Vitest测试createResource错误状态时触发未处理错误

问题现象

测试SolidJS组件时出现如下问题:组件在API返回404状态码时会渲染“Track not found”提示,正常运行时逻辑完全符合预期,但执行Vitest测试时会抛出错误:

Vitest caught 1 unhandled error during the test run. This might cause false positive tests.
涉及代码

Similar.tsx 组件代码

const Tracks: Component<Params> = (props) => {
  return (
    <Show
      when={!tracks.error}
      fallback={<ErrorMessage message="Track not found" />}
    >
      <div class="tracks">
        <For
          each={tracks()}
          fallback={<ErrorMessage message="No similar tracks found" />}
        >
          {(track) => (
            <Track
              name={track.name}
              artist={track.artist.name}
              image={track.image[3]['#text']}
              url={track.url}
            />
          )}
        </For>
      </div>
    </Show>
  );
};

测试用例代码

it('renders a "Track not found" message if API returns 404', async () => {
  vitest
    .spyOn(fetchSimilarTracks, 'default')
    .mockRejectedValueOnce(new Error('Track not found'));
  const { findByText } = renderSimilar({
    track: 'hdsauidhas',
    artist: 'hdsduhsd',
  });

  expect(await findByText('Track not found')).toBeInTheDocument();
});
问题原因

这个报错的核心是mock接口返回的rejected Promise没有被测试流程完整捕获:
你用mockRejectedValueOnce模拟接口报错后,Solid的createResource(即代码中用到的tracks响应式资源)会接收这个错误,更新tracks.error状态触发fallback渲染,整个UI逻辑是正确的。但这个rejected状态的Promise本身没有被任何await或者catch逻辑捕获,最终冒泡到Vitest的全局进程,触发了未处理错误告警。
findByText只会轮询等待目标文本出现在DOM中,不会等待组件内所有异步Promise都被处理完成,所以哪怕DOM断言通过,未捕获的Promise拒绝依然会触发Vitest的报错。

修复方案
  • 优先方案:主动捕获资源的rejected状态。如果renderSimilar工具函数能暴露内部创建的tracks资源引用,在findByText断言后补充await expect(tracks).rejects.toThrow('Track not found')即可,主动处理这个抛出的Promise,避免它变成全局未捕获错误。
  • 更贴合真实运行逻辑的方案:渲染测试组件时包裹一层和生产环境一致的错误边界组件,接住资源加载过程中抛出的错误,让错误处理流程和线上完全一致,从根源上避免错误冒泡到测试全局。
  • 临时兜底方案:如果确认组件错误处理逻辑完全正确,也可以在当前测试用例内临时重写未捕获reject的处理逻辑,但这种方式治标不治本,不推荐优先使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 14:54:19