2017-08-02 12 views
0

ノードスタイルのコールバックとBluebirdの約束を混ぜてコードを扱っています。そのために単体テストを書く必要があります。約束チェーンの終わりにコールバックを呼び出す

特に、cache.jsは、約束で動作するinit()の機能を公開しています。その後、他のファイル(例えば、index.js)内のdoSomething()関数によって呼び出され、init()の最後に呼び出されなければならないコールバックを受け入れます。

// [ cache.js ] 
function init() { 
    return performInitialisation() 
    .then((result) => return result); 
} 


// [ index.js ] 
var cache = require('./cache'); 

function doSomething(callback) { 
    console.log('Enter'); 

    cache.init() 
    .then(() => { 
     console.log('Invoking callback'); 
     callback(null); 
    }) 
    .catch((err) => { 
     console.log('Invoking callback with error'); 
     callback(err); 
    }); 

    console.log('Exit'); 
} 

可能ユニットテストは(唯一の関連するコードを示す)ことができる:次のように

擬似コードは、このテストに合格

// [ index.test.js ] 
... 
var mockCache = sinon.mock(cache); 
... 
it('calls the callback on success', function(done) { 
    mockCache.expects('init') 
    .resolves({}); 

    var callback = sinon.spy(); 

    doSomething(callback); 
    expect(callback).to.have.been.calledOnce; 
    done(); 
}); 

が、しかしnot.have.been.calledOnceに期待も通過変化、その間違っている。また

、コンソールログは、シーケンス外です:使用

  • チャイが-AS-約束し、例えば:

    Enter 
    Exit 
    Invoking callback 
    

    私が働いていたいずれもいくつかの可能性、見てきました単にあることdoSomething()をリファクタリングexpect(callback).to.eventually.have.been.calledOnce;

  • 関数のdoSomething(コールバック){ cache.init() .asCallback(コールバック)。 }

誰も私が私が間違っているのかを理解助けることができるとどのように私はそれをしてください修正できますか?

答えて

0

コンソールログは、あなたのPromiseは非常に少なくとも、非同期の意味になりますので、ログは正しい順序になっている

シーケンスの外で、内部コンソールログはthen & catchが上で実行されますに呼び出し、次のダニ。

なぜ、テストに失敗したのかという2つの問題があります。まず、sinon-chaiが正しく設定されていないか、またはcalledOnceアサーションが開始されていないようです。テストファイルの先頭には、何か必要があります:あなたはそれを持っており、それはまだsinon-chai LIB上の問題を開く価値があるかもしれませんその後、正しく動作していない場合は

const chai = require("chai"); 
const sinonChai = require("sinon-chai"); 

chai.use(sinonChai); 

は、しかし、簡単な回避策はsinon assertionsなどに切り替えることです

sinon.assert.calledOnce(callback) 

第2に、最終的にこれを修正すると、毎回テストが失敗することがあります。内部の約束が解決する機会があった前に、あなたのロギングで持っているテストで同じ問題を抱えているという理由があります。done取得の後、あなたはコールバックが呼ばれてきた:)

+0

ありがとうございました。 私が 'doSomething(()=> done());を実行すると、エラー状態をテストすることはできません。コールバックがエラー引数で呼び出されたかどうかはわかりません。 – rippeltippel

+0

@rippeltippelあなたがコールバックを処理しているので、 'done'が呼び出され、テストが成功するという事実があなたのチェックです。 'callback'が何らかの理由で呼び出されなかった場合、テストはタイムアウトになります。 – James

+0

意味があります、ありがとうございます。 – rippeltippel

0

James続い知って呼び出された場合、これを固定する最も簡単な方法は、実際に私はコメント '、あなたのdoneあなたのアサーションつまり

mockCache.expects('init').resolves({}); 
doSomething(() => done()); 

としてモカからハンドラを使用しています私のテストをこのように再訪しました:

it('calls the callback on success', function(done) { 
    mockCache.expects('init') 
    .resolves({}); 

    doSomething(done); 
}); 

it('calls the callback on error', function(done) { 
    mockCache.expects('init') 
    .rejects('Error'); 

    doSomething((err) => { 
    if (err === 'Error') { 
     done(); 
    } else { 
     done(err); 
    } 
    }); 
}); 
関連する問題