簡體   English   中英

如何使用 Jest 測試在 catch 語句中重新拋出錯誤

[英]How to test that an error is re-thrown in a catch statement with Jest

我有一個返回 promise 的 function,但我想測試它是否定義了一個 catch,然后另外測試它是否重新拋出錯誤。

這是一個非常人為的例子,但它是展示問題的最清晰的方式。 在我的實際代碼中,我正在調用模擬失敗的 function(與此示例中的手動拒絕相比),並且我在catch語句中有額外的日志記錄,這解釋了錯誤的重新拋出。

const foo = () => {
  return new Promise((resolve, reject) => {
    reject(new Error('reject')); // manually rejecting to mimic actual code...
  }).catch(error => {
    // do some additional logging...
    throw error;
  });
};

it('should catch and re-throw error', () => {
  // Received function did not throw
  // and
  // Unhandled promise rejection
  expect(() => foo()).toThrow();

  // Test passes, even when `throw error` is commented out with false positive
  expect(foo()).rejects.toThrow();
});

我可以成功檢查日志記錄 function 是否被調用,但無法弄清楚如何確保錯誤在之后重新拋出。

工作更新:)

感謝@skyboyer@Bergi讓我以不同的方式思考這個問題,並讓我接觸到一些有趣的笑話

下面是顯示日志記錄 function 的更新代碼,以及我確定的更新測試。

導致這種情況的問題是

  • 由於重新拋出錯誤,無法測試logging被調用
  • 無法測試重新拋出的錯誤的值

抓住被拒絕的 promise 讓我可以做到這兩點。

我本來打算在rejects.toEqual測試中離開,但現在看來是多余的......

對任何反饋感興趣! 再次感謝!

// myModule.js
export const logging = () => {};
export const bar = () => new Promise(resolve => {});
export const foo = () => {
  return bar().catch(error => {
    logging();
    throw error;
  });
};

describe('myModule', () => {
  let fooReturn;

  beforeEach(() => {
    jest.clearAllMocks();

    jest.spyOn(myModule, 'bar').mockImplementation(() => {
      return Promise.reject({ error: 'bar error' });
    });

    jest.spyOn(myModule, 'logging').mockImplementation(() => {});

    fooReturn = myModule.foo();
  });

  it('should catch and re-throw error', () => {
    expect.assertions(1);
    fooReturn.catch(result => expect(result).toEqual({ error: 'bar error' }));

    // removed since the above test covers that the promise was rejected
    // return fooReturn.rejects.toEqual(expect.anything());
  });

  it('should call the loggin method', async () => {
    expect.assertions(1);

    // prevents UnhandledPromiseRejectionWarning
    fooReturn.catch(() => {});

    expect(myModule.logging).toBeCalled();
  });
});

你錯過了return

https://jestjs.io/docs/asynchronous#resolves——拒絕

請務必返回斷言——如果您省略此返回語句,您的測試將在解析從 fetchData 返回的 promise 之前完成,然后 then() 有機會執行回調。

你的測試應該是

it('should catch and re-throw error', () => {
  return expect(foo()).rejects.toEqual(expect.anything());
});

正如你/Bergi 注意到的那樣, async/await看起來更簡潔:

it('should catch and re-throw error', async () => {
  await expect(foo()).rejects.toEqual(expect.anything());
});

但是如果我們錯過了在expect之前添加await ,我們將遇到與沒有return的版本 1 中完全相同的問題。 所以要小心。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM