【问题标题】:Jest mock promise rejection to enforce rejection in calling function开玩笑模拟承诺拒绝以在调用函数中强制拒绝
【发布时间】:2022-01-20 07:26:59
【问题描述】:

我正在尝试使用 Jest 测试以下 get 函数。如何测试/模拟 localForage.getItem 中的 Promise 拒绝,以便我可以测试 get catch 块?

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.");
  }
}

我尝试了以下方法:

  test('test get promise rejection', async () => {
    const expectedError = new Error(
      'The key (' + 'fghgdfghfghfdh' + ") isn't accessible."
    );
    jest.fn(localforage.getItem).mockRejectedValue(new Error());
    expect(get('fghgdfghfghfdh')).rejects.toThrow(expectedError);
  });

但我收到以下错误:

node:internal/process/promises:246
          triggerUncaughtException(err, true /* fromPromise */);
          ^

[UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "Error: expect(received).rejects.toThrow()

Received promise resolved instead of rejected
Resolved to value: null".] {
  code: 'ERR_UNHANDLED_REJECTION'
}

【问题讨论】:

    标签: javascript typescript unit-testing jestjs mocha.js


    【解决方案1】:

    嗯...我们从这一行中删除 await 关键字

    expect(await get('fghgdfghfghfdh')).rejects.toThrow(expectedError);
    

    因为错误明确说明

    接收到的值必须是一个承诺或返回一个承诺的函数

    然后测试失败,因为它预计会被拒绝并使用null 值解决

    所以,要么调用 get 而不使用密钥

     expect(get()).rejects.toThrow(expectedError);
    

    或者像这样让get函数更具防御性

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

    使用哪种方法?我认为两者都......无论如何我希望你能顺利完成你的测试!

    【讨论】:

    • 我想专门测试catch阻止throw new Error('The key (' + key + ") isn't accessible: ");
    【解决方案2】:

    我得到它的工作,我不得不用jest.fn().mockRejectedValue替换localforage.getItem:

    test('test get promise rejection', async () => {
      localforage.getItem = jest.fn().mockRejectedValue(new Error());
    
      const expectedError = new Error(
        'The key (' + 'fghgdfghfghfdh' + ") isn't accessible."
      );
      expect(handler.get('fghgdfghfghfdh')).rejects.toThrow(expectedError);
    });
    

    【讨论】:

      猜你喜欢
      • 2021-01-10
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 2019-09-15
      • 1970-01-01
      • 2019-11-25
      • 2021-03-16
      • 1970-01-01
      相关资源
      最近更新 更多