簡體   English   中英

測試 Promise 超時 Jest

[英]Test Promise with timeout Jest

我有一個簡單的代碼可以在 1 秒后解析:

const promiseWithTimeout = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve({id: 3});
    }, 1000);
  });
};

我正在嘗試使用 jest 進行測試,但是,使用 resolves 或 awaits 可以使測試通過,即使是錯誤的期望(未處理的拒絕)。 如果我嘗試進行失敗的測試,即使期望失敗,它也會通過

我試過的

it("Should return the right ID", ()=>{
    expect.assertions(1);
    expect(promiseWithTimeout()).resolves.toEqual({id: 3});    // this one works fine
    jest.advanceTimersByTime(1000)

  })
it("Should return the right ID", ()=>{
    expect.assertions(1);
    expect(promiseWithTimeout()).resolves.toEqual({id: 4});    // this PASSES , but shows 
    // UnhandledPromiseRejectionWarning: Error: expect(received).resolves.toEqual(expected) // deep equality
    jest.advanceTimersByTime(1000)

  })

我預計它會失敗並表明對象是不同的。

我也嘗試過使用 then ,但仍然是同樣的問題

你有幾個選擇 -

從您的測試中返回 promise

這將通過 -

it("should return the id", () => {
  return promiseWithTimeout().then(m => {  // return
    expect(m.id).toBe(3)                   // ✓
  })
})

這將失敗 -

it("should return the id", () => {
  return promiseWithTimeout().then(m => {  // return
    expect(m.id).toBe(4)                   // ✕ id 4
  })
})

異步..等待

這將通過 -

it("should return the id", async () => {   // async
  const m = await promiseWithTimeout()     // await
  expect(m.id).toBe(3)                     // ✓
})

這將失敗 -

it("should return the id", async () => {
  const m = await promiseWithTimeout()
  expect(m.id).toBe(4)                     // ✕ id 4
})

.resolves 和.rejects

請注意,您必須return預期的 promise。 這將通過 -

it("should return the id", ()=>{
  return expect(promiseWithTimeout()).resolves.toEqual({id: 3}) // ✓
})

這將失敗 -

it("should return the id", ()=>{
  return expect(promiseWithTimeout()).resolves.toEqual({id: 4}) // ✕ id 4
})

使用 jest.advanceTimersByTime

Jest 允許您“偽造”計時器,以便測試可以快速運行,同時仍確保異步代碼的行為正確。 在您的測試文件中,您必須包含jest.useFakeTimers()並且您的測試必須使用上述技術之一。 在這里,我們return預期的承諾 -

jest.useFakeTimers()

it("should return the id", () => {
  const p = promiseWithTimeout()
  jest.advanceTimersByTime(1000)               // advance timers
  return expect(p).resolves.toEqual({ id: 3 }) // ✓
})

這將失敗 -

jest.useFakeTimers()

it("should return the id", () => {
  const p = promiseWithTimeout()
  jest.advanceTimersByTime(1000)
  return expect(p).resolves.toEqual({ id: 4 })  // ✕ id 4
})

使用 expect.assertions

在許多情況下,您不需要指定expect.assertions 例如,當使用.resolves期望時,如果 promise 拒絕,我們將獲得斷言失敗 -

const promiseWithTimeout = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject({ id: 3 })                       // reject
    }, 1000)
  })
}

jest.useFakeTimers()

it("should return the id", () => {
  const p = promiseWithTimeout()
  jest.advanceTimersByTime(1000)
  return expect(p).resolves.toEqual({ id: 3 }) // ✕ rejected
})

如果您希望 promise 被拒絕,請使用.catch method ,然后添加expect.assertions以驗證是否調用了一定數量的斷言。 否則,完成的 promise 不會通過測試 -

test('the fetch fails with an error', () => {
  expect.assertions(1)                      // expect assertions
  return fetchData().catch(e => expect(e).toMatch('error')) // ✓
})

有關更多信息,請參閱 Jest 文檔中的測試異步代碼

暫無
暫無

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

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