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

如何在Jest快照测试失败时显示自定义错误信息?

如何在Jest快照测试失败时显示自定义错误信息?

嗨,我来帮你搞定这个问题!你遇到的try/catch没生效的情况,大概率是因为Jest对断言失败的错误处理机制比较特殊——它会优先拦截断言抛出的错误,导致你的catch块有时候没法触发。不过别担心,有几种靠谱的方法能实现你想要的效果:

方法一:自定义Jest匹配器(最推荐)

这种方式最优雅,直接扩展Jest的断言能力,让快照失败时自动追加你的提示信息。你可以在测试文件顶部或者全局的Jest配置文件里添加这段代码:

// 扩展Jest匹配器,添加带自定义提示的快照断言
expect.extend({
  toMatchSnapshotWithReminder(received) {
    // 调用Jest原生的快照匹配逻辑
    const { pass, message } = this.equals(received, expect.getState().snapshotState.match(received));
    
    if (!pass) {
      // 失败时追加自定义提示
      return {
        pass: false,
        message: () => `${message()}\n\n💡 注意:页面快照已变更。如果这是有意修改,请记得同步更新MY_CONSTANT常量!`
      };
    }
    return { pass: true };
  }
});

然后在你的测试里替换原来的断言就行:

describe('My Page', () => {
  it('matches the snapshot', () => {
    const { asFragment } = render(<MyComponent />);
    // 使用自定义的匹配器
    expect(asFragment()).toMatchSnapshotWithReminder();
  });
});

这样一来,只要快照测试失败,你的自定义提示就会和Jest原生的错误信息一起显示出来,开发者一眼就能看到。

方法二:修复try/catch的使用方式

如果不想自定义匹配器,也可以调整你的try/catch代码,确保Jest能正确捕获到你抛出的自定义错误。比如:

describe('My Page', () => {
  it('matches the snapshot', () => {
    const { asFragment } = render(<MyComponent />);
    try {
      expect(asFragment()).toMatchSnapshot();
    } catch (error) {
      // 创建新的错误对象,保留原始栈信息,同时追加提示
      const customError = new Error(
        `${error.message}\n\n注意:页面快照已变更。如果这是有意修改,请记得同步更新MY_CONSTANT常量!`
      );
      customError.stack = error.stack;
      throw customError;
    }
  });
});

如果你的组件里有异步更新(比如用了useEffect),记得把测试改成异步的,先等待组件渲染完成再断言:

describe('My Page', () => {
  it('matches the snapshot', async () => {
    const { asFragment } = render(<MyComponent />);
    // 等待组件异步更新完成
    await waitFor(() => {});
    
    try {
      expect(asFragment()).toMatchSnapshot();
    } catch (error) {
      error.message += '\n\n注意:页面快照已变更。如果这是有意修改,请记得同步更新MY_CONSTANT常量!';
      throw error;
    }
  });
});

方法三:用afterEach钩子输出提示

还有一种偷懒的办法——在测试块里加个afterEach钩子,每次测试结束后检查是否失败,如果失败就打印你的提示:

describe('My Page', () => {
  afterEach(() => {
    const testState = expect.getState();
    // 获取最后一个测试的结果
    const lastResult = testState.testResults[testState.testResults.length - 1];
    if (lastResult.status === 'failed') {
      console.log('\n💡 注意:页面快照已变更。如果这是有意修改,请记得同步更新MY_CONSTANT常量!');
    }
  });

  it('matches the snapshot', () => {
    const { asFragment } = render(<MyComponent />);
    expect(asFragment()).toMatchSnapshot();
  });
});

这种方法不需要修改原有的断言,适合快速临时添加提示的场景。

备注:内容来源于stack exchange,提问作者Attila

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.14 08:58:07