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

如何使用Jest模拟localForage.getItem的Promise拒绝以测试get方法的Catch代码块?

如何测试Jest中localForage.getItem的Promise拒绝场景?

看起来你的测试代码在mock localForage.getItem的方式上出了问题,导致实际调用的还是原方法(或者默认的mock实现),所以Promise被resolved而不是rejected,进而触发了未处理的拒绝错误。我来帮你修正这个测试,同时解释问题所在:

问题分析

你的测试代码里jest.fn(localforage.getItem).mockRejectedValue(new Error())这一行是错误的:

  • jest.fn(originalFn)会创建一个新的mock函数,但不会替换原对象上的方法。也就是说,你的get函数调用的依然是原本的localforage.getItem,而不是你刚创建的mock函数。
  • 另外,测试中没有用await等待expect(...).rejects完成,Jest可能在Promise处理结束前就结束测试,导致未捕获的Promise拒绝。

正确的测试方案

根据你的代码结构(假设get是某个类的方法,依赖this.localForage),我们需要正确mock localForage的实例或者模块:

情况1:get是类的方法(依赖注入localForage)

如果你的代码是类的形式,比如:

import type LocalForage from 'localforage';

class StorageService {
  private localForage: LocalForage;

  constructor(localForageInstance: LocalForage) {
    this.localForage = localForageInstance;
  }

  async get<T>(key: string): Promise<T | null> {
    if (!key) {
      return Promise.reject(new Error('There is no key to get!'));
    }
    try {
      return await this.localForage.getItem(key);
    } catch (err) {
      throw new Error(`The key (${key}) isn't accessible.`);
    }
  }
}

对应的测试代码应该这样写:

import { StorageService } from './storage-service';
import localforage from 'localforage';

// 先mock整个localforage模块
jest.mock('localforage');

test('get方法在localForage.getItem拒绝时抛出正确错误', async () => {
  const testKey = 'fghgdfghfghfdh';
  const expectedError = new Error(`The key (${testKey}) isn't accessible.`);

  // 将mock后的getItem方法设置为拒绝状态
  (localforage.getItem as jest.Mock).mockRejectedValue(new Error('Mocked failure'));

  // 创建类实例,传入mock的localforage
  const storageService = new StorageService(localforage);

  // 用await等待Promise处理完成,确保Jest捕获拒绝情况
  await expect(storageService.get(testKey)).rejects.toThrow(expectedError);
});

情况2:get是独立函数(直接导入localForage)

如果你的get函数是直接使用导入的localforage:

import localforage from 'localforage';

async function get<T>(key: string): Promise<T | null> {
  if (!key) {
    return Promise.reject(new Error('There is no key to get!'));
  }
  try {
    return await localforage.getItem(key);
  } catch (err) {
    throw new Error(`The key (${key}) isn't accessible.`);
  }
}

测试代码类似,只需要调整调用方式:

import { get } from './your-file-path';
import localforage from 'localforage';

jest.mock('localforage');

test('get函数在localForage.getItem拒绝时抛出正确错误', async () => {
  const testKey = 'fghgdfghfghfdh';
  const expectedError = new Error(`The key (${testKey}) isn't accessible.`);

  (localforage.getItem as jest.Mock).mockRejectedValue(new Error('Mocked failure'));

  await expect(get(testKey)).rejects.toThrow(expectedError);
});

关键注意事项

  1. 必须mock整个模块:用jest.mock('localforage')让Jest替换所有对localforage的引用为mock对象,这样才能控制getItem的行为。
  2. 类型断言:因为TypeScript不知道localforage.getItem已经被mock,所以需要用as jest.Mock来告诉TypeScript这是一个mock函数。
  3. 等待Promise完成:一定要用await配合expect(...).rejects,否则Jest会在Promise处理结束前结束测试,引发未处理的Promise拒绝错误。

内容的提问来源于stack exchange,提问作者BuZZ-dEE

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 09:57:27