2017-04-21 16 views
2

私はmochaユニットテストのセットでbeforeブロックを使用しています。その中にREST APIから情報を取得する一連の呼び出しを繰り返しています。私はこれを行うにはchai-httpを使用しています。しかし、私はdone()メソッドが呼び出されているという問題に遭遇しています。これまでに完了した一連のnリクエストが完了しました。最後のブロックで呼び出しを実行すると、複数のdone()コールが返されますが、ブロックの外に置くと、実際に完了する前に呼び出されます。ここではブロックの前の例である:ブロック前に複数のchai-http要求が実際にモカで完了したことを確認するにはどうすればよいですか?

var flags = []; 
var groups = []; 

// This functions correctly 1 done() called at the end 
before(function(done) { 
    chai.request(server) 
     .get('/groups') 
     .end(function(err, res){ 
      groups = JSON.parse(res.text); 
      done(); 
     }); 
    }); 

before(function(done) { 
    groups.forEach(function(rec) { 
     chai.request(server) 
      .get('/groups/' + rec.KEYWORD_GROUP_ID + '/groupflags') 
      .end(function(res, err) { 
       Array.prototype.push.apply(flags, JSON.parse(res.text)); 
       // A done() here gets called n times 
       }); 
     // But here it's called before the requests all end 
     done(); 
     }); 

は、これらの要求のすべてが完了したときに、私は私のテストを確実にするために、単一のdone()を呼び出すことができます検出する方法はありますが唯一のセットアップ正しいコンテキストで実行されていますか?

答えて

1

async.whilst()で試すことができます。 groups.lengthのカウンタをカウントアップし、コールバックでdone()を押します。機能のドキュメントへのリンク:(http://caolan.github.io/async/docs.html#whilst

のような何か...

let counter = 0; 
async.whilst(
    () => { 
     // Test if we have processed all records 
     return counter < groups.length; 
    }, 
    (callback) => { 
     let rec = groups[counter++]; // Sorry Douglas 
     chai.request(server) 
      .get('/groups/' + rec.KEYWORD_GROUP_ID + '/groupflags') 
      .end(function (res, err) { 
       Array.prototype.push.apply(flags, JSON.parse(res.text)); 
       callback(null, counter); 
      }); 
    }, 
    (err) => { 
     assert(!err, err); 
     done(); 
    } 
); 
+0

私は単純な数を試してみましたが、非同期ライブラリの方がはるかに柔軟で、一般的なケースの方がうまく収まるようです。 – JavaDevGuy

+0

確かに、受け入れていただきありがとうございます。あなたのオリジナルの質問の下に編集としてあなたのソリューションを投稿できますか?私はあなたがカウンターと非同期性の問題をどのように解決したかに興味があります。 – atripes

2

アレックスはここに要求されたように、私は解決策として最初に持っていたものです:

before('delete keywords in a group', function(done) { 
    var count = 0; 
    var length = groups.length; 

    if (length === 0) {done();} 

    groups.forEach(function (rec) { 
     chai.request(server) 
      .delete('/keywords/' + rec.id) 
      .end(function (err, res) { 
       if (err) { 
        console.error('Delete keywords err: ' + err.message); 
        this.skip(); 
       } else { 
        count++; 
        if (count === length) {done();} 
        } 
      }); 
     }); 
    }); 

これが動作しているようですしかし、私は、より複雑なケース(例えば、カスケードスタイルの削除)のために、非同期ライブラリは、よりエレガントで信頼性の高いソリューションを提供すると思います。したがって、一般的な場合にはより適しています。