2017-10-24 8 views
1

セッショントークンをチェックして、ユーザーが管理者かどうかを確認するミドルウェア機能があります。すべてのチェックが合格しただけで、next()を呼び出すと、関数は何も返しません。sinonスパイでアサーションを行う前に、sinon stubbed約束を待つのを待つ

Sinonスパイであるnext()コールバックでアサーションを行う前に、内部の非同期Promise(adminPromise)が解決するのを待つ方法はありますか?テストのアサーションはAdminMiddleware.prototype.runの約束を解決する前に行われるため、テストは現在失敗します。

機能は次のとおりです。

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(); 
}); 

。さらに、失敗すると、未処理の約束拒否エラーが発生し、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(); 
    }); 
}); 

答えて

0

1つの解決策は、スパイの代わりにスタブを使用することです。彼らは2つの異なったものですが、匿名のスパイを使用していたので、このケースでは機能を失うことはありません。 「nextSpyが呼び出されていない場合は、まだタイムアウトエラーになりますこれらの2つの例では

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); 
}); 

、次のことができます。

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使用を避けるなど何かができますその周りに合理的な方法を考える必要はありません。未処理の約束の拒絶は避けることが非常に重要だった場合、私はあなたがこのような何かを行うことができたとします

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

は、それはまだタイムアウトによりテストを失敗していました、しかし、それは、未処理の約束拒否エラーをスローしません。

関連する問題