测试是否调用了带有 Promise 的方法 (Jest)

Testing if method with Promise was called (Jest)

我有一个初始化方法调用另一个 returns 承诺的方法,例如:

  initStuffAfterLoad() {
    const _this = this;
    const theInterval = window.setInterval(function() {
      if (thing) {
        window.clearInterval(theInterval);
        _this.getBanana()
          .then(response => {
            _this.getApple(response, _this);
          });
      }
    }, 100);
  }

并且我需要测试 getBanana 是否被调用 (jest/sinon)。到目前为止我有:

  test('init function calls getBanana', () => {
    let thing = true
    const getBananaSpy = sinon.spy();
    sinon.stub(TheClass.prototype, 'getBanana').callsFake(getBananaSpy).resolves();

    jest.useFakeTimers();
    TheClass.prototype.initStuffAfterLoad();
    jest.runOnlylPendingTimers();

    expect(getBananaSpy.called).toBeTruthy();
    TheClass.prototype.getBanana.restore();
 });

但是它仍然在断言时收到 false。我认为我没有正确处理 Promise 部分 - 执行此操作的最佳实践方法是什么?

我对 sinon 不熟悉,但这里有一种纯开玩笑的方式来满足您的需求(更好的是它还检查 getBanana 解析时是否调用了 getApple :))

jest.useFakeTimers()

const _this = {
    getBanana: () => {},
    getApple: () => {}
}

const initStuffAfterLoad = () => {
    const theInterval = window.setInterval(function() {
        window.clearInterval(theInterval);
        _this.getBanana().then(response => {
            _this.getApple(response, _this)
        });
    }, 100);
}

test('', () => {
    let result

    _this.getBanana = jest.fn(() => {
        result = new Promise( resolve => { resolve() } )
        return result
    })
    _this.getApple = jest.fn()

    initStuffAfterLoad()    

    jest.runAllTimers()
            
    expect(_this.getBanana.mock.calls.length).toBe(1)
    return result.then(() => {
        expect(_this.getApple.mock.calls.length).toBe(1)
    })
})

代码测试:)


PASS test\temp.test.js √ (25ms)

Test Suites: 1 passed, 1 total

Tests: 1 passed, 1 total

Snapshots: 0 total

Time: 2.489s