如何使用 Jest 测试 img.onload?

Max*_*vis 11 javascript unit-testing jestjs

我被困在img.onload事件测试中。我知道这是一个异步操作,它应该被嘲笑,但我仍然无法弄清楚如何解决这个问题。我也见过几个类似的案例,但它们与这个不同。

以前访问过:

测试代码:

  function funcToTest(img, callback) {
    const img = new Image()
    img.src = img

    img.onload = () => {
      callback(true) // should return callback with true on finish
    }

    img.onerror = (e) => {
      callback(false) // should return callback with false on error
      console.log(e) 
    }
  }

  funcToTest()
Run Code Online (Sandbox Code Playgroud)

测试环境:

describe('tet it', () => {
  it('test', done => {
    const callback = status => {
      expect(status).toEqual(true) // but nothing happen
      done()
    }

    funcToTest('some_image', callback)
  })
})
Run Code Online (Sandbox Code Playgroud)

另外我在完成时遇到错误:

    Timeout - Async callback was not invoked within the 5000ms timeout specified by jest.setTimeout.
        > 2 |   it('test', done => {...

Run Code Online (Sandbox Code Playgroud)

提前致谢!

Pat*_*ick 11

虽然回答了这个问题,但我不同意解决方案的目的。

我们不应该编写测试来通过覆盖率,我们应该编写测试来证明一个观点,并确保代码片段按预期运行。

测试它的方法是模拟 Image 构造函数并将其替换为将调用该onload函数的内容。

describe('tet it', () => {

  it('test', done => {
    global.Image = class {
      constructor() {
        setTimeout(() => {
          this.onload(); // simulate success
        }, 100);
      }
    }

    const callback = status => {
      done()
    }

    funcToTest('some_image', callback)
  })
})

Run Code Online (Sandbox Code Playgroud)

该方法只是假设“浏览器”将在 100 毫秒内下载图像,beforeEach如果您需要在测试之间共享此行为,您可以调整失败的代码,或者将其部分移动到。

  • @Jago 这是一个打字稿错误,上面的代码不是用安全打字稿编写的。这里的模拟图像显然不是完全模拟的图像实现。如果我是你,我会忽略它,因为可能不值得在这里添加类型安全的麻烦 (2认同)