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

Vue+Jest测试:Promise抛异常后验证Toast错误提示失败

问题分析与解决方案

核心问题点

  1. 组件内Toast调用对象不一致:你的deleteUser方法中,成功回调用this.$toast.open,但异常回调误用了this.$st.toast.open,导致测试断言的对象与实际调用对象不匹配。
  2. 异步函数Mock方式错误:异常场景中直接同步抛出错误,而fontService.deleteUser作为异步方法应该返回Promise,同步抛错无法被Promise的catch块捕获。
  3. 测试断言与Mock对象不匹配:成功场景中Mock了wrapper.vm.$toast.open,但断言的却是wrapper.vm.$st.toast.open,属于笔误;异常场景同样存在这个问题。

修复步骤

1. 修正组件方法的Toast调用

将deleteUser方法中catch块的this.$st.toast改为this.$toast,保持和成功场景一致:

async deleteUser(userId) {
    this.setLoading(true);
    fontService
      .deleteUser(userId)
      .then(() => {
        this.$toast.open({
          type: 'success',
          content: 'User was successfully deleted',
        });
        this.getFonts();
      })
      .catch(() => {
        // 修正此处的$st.toast为$toast
        this.$toast.open({
          type: 'error',
          content: 'There was an error trying to delete this font. Please try again.',
        });
      })
      .finally(() => {
        this.setLoading(false);
      });
  }

2. 修正异常场景的Mock方式

使用mockRejectedValueOnce返回一个rejected状态的Promise,而不是同步抛错:

it('shows an error toast trying to delete', async () => {
  // 用mockRejectedValueOnce模拟异步方法抛出异常
  jest.spyOn(fontService, 'deleteUser').mockRejectedValueOnce(new Error('error'));
  const wrapper = await createWrapper();
  // 统一Mock$toast.open
  wrapper.vm.$toast.open = jest.fn();
  // await异步方法,确保Promise链执行完成
  await wrapper.vm.deleteUser('my_user_id');

  expect(wrapper.vm.$toast.open).toBeCalledWith({
    type: 'error',
    content: 'There was an error trying to delete this font. Please try again.',
  });
});

3. 修正成功场景的断言对象

成功场景中同样需要将断言对象改为wrapper.vm.$toast.open,与Mock对象保持一致:

it('shows a success toast after delete', async () => {
  jest.spyOn(fontService, 'deleteUser').mockResolvedValueOnce(true);
  const wrapper = await createWrapper();
  wrapper.vm.$toast.open = jest.fn();
  await wrapper.vm.deleteUser('my_user_id');

  expect(wrapper.vm.$toast.open).toBeCalledWith({
    type: 'success',
    content: 'User was successfully deleted',
  });
});

额外说明

  • 对于异步方法的测试,直接await方法调用比仅await $nextTick更可靠,因为它会等待整个Promise链的所有微任务执行完成。
  • 如果你的项目中使用了@vue/test-utils,也可以使用flushPromises()辅助函数来确保所有异步操作完成。

内容的提问来源于stack exchange,提问作者Marcelo J Forclaz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 01:00:58