私のノードアプリケーションでは、私は自分のコードをテストするためにモカを使っています。モカを使用して多くの非同期関数を呼び出している間、私はタイムアウトエラー(Error: timeout of 2000ms exceeded.
)を得ています。どうすればこれを解決できますか?
var module = require('../lib/myModule');
var should = require('chai').should();
describe('Testing Module', function() {
it('Save Data', function(done) {
this.timeout(15000);
var data = {
a: 'aa',
b: 'bb'
};
module.save(data, function(err, res) {
should.not.exist(err);
done();
});
});
it('Get Data By Id', function(done) {
var id = "28ca9";
module.get(id, function(err, res) {
console.log(res);
should.not.exist(err);
done();
});
});
});
テスト実行時にタイムアウトを設定できます。
mocha --timeout 15000
または、各スイートまたは各テストのタイムアウトをプログラムで設定することもできます。
describe('...', function(){
this.timeout(15000);
it('...', function(done){
this.timeout(15000);
setTimeout(done, 15000);
});
});
詳しくは docs をご覧ください。
タイムアウトを増やすだけの「解決策」が、実際に起こっていることを覆い隠していることがわかりました。
Mochaがコールバックからアサーションエラーを受け取らないとき、あなたは通常#2に遭遇します。これは、他のコードが例外をスタックの上にさらに飲み込むことによって引き起こされます。 これに対処する正しい方法は、コードを修正し、エラーを飲み込まないことです。
外部コードがあなたのエラーを飲み込んだとき
それがあなたが修正することができないのがライブラリ関数である場合、あなたはアサーションエラーを捕らえて自分でMochaにそれを渡す必要があります。これを行うには、アサーションコールバックをtry/catchブロックでラップし、例外をdoneハンドラに渡します。
it('should not fail', function (done) { // Pass reference here!
i_swallow_errors(function (err, result) {
try { // boilerplate to be able to get the assert failures
assert.ok(true);
assert.equal(result, 'bar');
done();
} catch (error) {
done(error);
}
});
});
この定型文は、テストをもう少し見やすくするためのユーティリティ関数に抽出できます。
it('should not fail', function (done) { // Pass reference here!
i_swallow_errors(handleError(done, function (err, result) {
assert.equal(result, 'bar');
}));
});
// reusable boilerplate to be able to get the assert failures
function handleError(done, fn) {
try {
fn();
done();
} catch (error) {
done(error);
}
}
ネットワークテストのスピードアップ
それ以外は、機能しているネットワークに頼らなくてもテストに合格するために、ネットワーク呼び出しにテストスタブを使用し始めることに関するアドバイスを選択することをお勧めします。 Mocha、Chai、Sinonを使用すると、テストは次のようになります。
describe('api tests normally involving network calls', function() {
beforeEach: function () {
this.xhr = sinon.useFakeXMLHttpRequest();
var requests = this.requests = [];
this.xhr.onCreate = function (xhr) {
requests.Push(xhr);
};
},
afterEach: function () {
this.xhr.restore();
}
it("should fetch comments from server", function () {
var callback = sinon.spy();
myLib.getCommentsFor("/some/article", callback);
assertEquals(1, this.requests.length);
this.requests[0].respond(200, { "Content-Type": "application/json" },
'[{ "id": 12, "comment": "Hey there" }]');
expect(callback.calledWith([{ id: 12, comment: "Hey there" }])).to.be.true;
});
});
詳しくは Sinonのnise
docs をご覧ください。
少し遅れましたが、将来誰かがこれを使用できるようになります。package.jsonのスクリプトを次のように更新することで、テストのタイムアウトを長くすることができます。
"scripts": { "test": "test --timeout 10000" //Adjust to a value you need }
コマンドtest
を使用してテストを実行します。
私にとって問題は、実際にはdescribe関数です。これは、arrow関数が提供されると、mochaにタイムアウトを見逃させ、一貫して動作しません。 (ES6を使用)
describeブロック内で失敗したさまざまなテストに対して、このエラーが常に発生するという約束は拒否されなかったため、
正しく動作していないときにこのように見えるので、これは:
describe('test', () => {
assert(...)
})
これは無名関数を使って機能します
describe('test', function() {
assert(...)
})
それが誰かに役立つことを願って、上記のための私の設定:(nodejs:8.4.0、npm:5.3.0、mocha:3.3.0)
私の問題は応答を返送しなかったため、ハングしていました。エクスプレスを使用している場合は、res.send(data)、res.json(data)、または使用するapiメソッドがテストするルートに対して実行されることを確認してください。