簡體   English   中英

在對sinon間諜作出斷言之前,等待sinon頑固的承諾解決

[英]wait for sinon stubbed promise to resolve before making assertion on sinon spy

我有一個中間件功能,它檢查會話令牌以查看用戶是否是管理員用戶。 如果所有檢查都通過但是只調用next(),則該函數不返回任何內容。

在對作為Sinon間諜的next()回調進行斷言之前,我如何等待內部異步Promise(adminPromise)解決? 測試將失敗,因為測試中的斷言是在AdminMiddleware.prototype.run中解析promise之前做出的。

功能是:

AdminMiddleware.prototype.run = function (req, res, next) {
  let token        = req.header(sessionTokenHeader);
  let adminPromise = new admin().send()

  adminPromise.then(function (authResponse) {
    let adminBoolean = JSON.parse(authResponse).payload.admin;

    if (adminBoolean !== true) {
      return new responseTypes().clientError(res, {
          'user': 'validation.admin'
      }, 403);
    };

    next();
  });
};

而且測試:

it('should call next once if admin', function (done) {
    stub = sinon.stub(admin.prototype, 'send');
    stub.resolves(JSON.stringify({success : true, payload : {admin : true}}));
    let nextSpy = sinon.spy();

    AdminMiddleware.prototype.run({header: function () {}}, {}, nextSpy);
    expect(nextSpy.calledOnce).to.be.true;
    done();
});

目前,我正在將期望包裝在下面,這將導致測試通過,但看起來像是一個黑客。 此外,如果它失敗,它將導致未處理的promise拒絕錯誤和由於done()未被調用而超時。

    it('should call next once if admin', function (done) {
    stub = sinon.stub(admin.prototype, 'send');
    stub.resolves(JSON.stringify({success : true, payload : {admin : true}}));
    let nextSpy = sinon.spy();

    AdminMiddleware.prototype.run({header: function () {}}, {}, nextSpy);
    stub().then(function () {
        expect(nextSpy.calledOnce).to.be.true;
        done();
    });
});

一種解決方案是使用存根而不是間諜。 雖然它們是兩個不同的東西,但我並沒有看到你在這種情況下失去任何功能,因為你使用的是匿名間諜。

AdminMiddleware.prototype.run = function (req, res, next) {
    const adminPromise = Promise.resolve()

    adminPromise.then(function (authResponse) {
        next()
    })
}

it('should call next once if admin', function (done) {
    const nextSpy = sinon.stub()
    nextSpy.callsFake(() => {
        expect(nextSpy.called).to.be.true
        done()
    })
    AdminMiddleware.prototype.run({header: function () {}}, {}, nextSpy);
});

此外,您可以完全避免將sinon用於此斷言,並執行以下操作:

it('should call next once if admin', function (done) {
    let called
    const nextSpy = function() {
        called = true
        expect(called).to.be.true
        done()
    }
    AdminMiddleware.prototype.run({header: function () {}}, {}, nextSpy);
});

在這兩個示例中,如果未調用nextSpy,您仍會收到超時錯誤,無法想出任何合理的方法。 如果未處理的承諾拒絕是非常重要的,我想你可以做這樣的事情:

nextSpy.callsFake(() => {
    try {
        expect(nextSpy.called).to.be.false
        done()
    } catch (e) {
        console.log(e)
    }
})

由於超時,它仍然會通過測試失敗,但它不會拋出未處理的承諾拒絕錯誤。

暫無
暫無

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

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