Dalam pengujian moka saat memanggil fungsi asinkron bagaimana menghindari batas waktu Kesalahan: batas waktu 2000 ms terlampaui

200

Dalam aplikasi simpul saya, saya menggunakan moka untuk menguji kode saya. Saat memanggil banyak fungsi asinkron menggunakan moka, saya mengalami kesalahan batas waktu ( Error: timeout of 2000ms exceeded.). Bagaimana saya bisa menyelesaikan ini?

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

    });

});
sachin
sumber
apakah ini tes integrasi? sudah banyak waktu untuk menjalankan tes - mungkin Anda harus mempertimbangkan bertopik - github.com/thlorenz/proxyquire mungkin membantu Anda.
surui
@surui terima kasih saya akan melihatnya
sachin
Bolehkah saya merekomendasikan menggunakan janji untuk hal-hal yang tidak sinkron dan mengujinya sangat mudah dengan Chai sebagai janji
Krym

Jawaban:

344

Anda dapat mengatur batas waktu saat menjalankan tes Anda:

mocha --timeout 15000

Atau Anda dapat mengatur batas waktu untuk setiap suite atau setiap tes secara terprogram:

describe('...', function(){
  this.timeout(15000);

  it('...', function(done){
    this.timeout(15000);
    setTimeout(done, 15000);
  });
});

Untuk info lebih lanjut, lihat dokumen .

Andreas Hultgren
sumber
3
versi yang lebih pendek -t. jika Anda menggunakan mocha-test untuk menjalankan mocha dari tugas kasar, ini juga didukung di objek pilihan options:{timeout:15000}.
svassr
5
FYI: meneruskan fungsi panah ke Mocha tidak disarankan. mochajs.org/#arrow-functions
c0ming
4
Fungsi panah tidak disarankan di tautan di atas. Itu hanya mengatakan Anda hanya perlu tahu apa yang mereka lakukan sehingga Anda tidak gagal ketika perlu mengakses konteksnya. Saya tidak pernah membutuhkan konteksnya, karena mengandalkan timeout itu rapuh, dan semua tes saya berjalan dalam beberapa ms, tetapi saya menemukan masalah yang sama ketika menggunakan sinon-test. Masih menggunakan lambdas 99% dari waktu.
oligofren
26
TypeError: this.timeout is not a functionsaat menggunakan"mocha": "^3.5.0"
Junior Mayhé
5
@ apakah Anda yakin tidak menggunakan fungsi panah? Mengenai async / tunggu itu ada di dokumen jadi harus bekerja (dan hal yang sama seperti menggunakan janji). Kedengarannya seperti pertanyaan lain.
Andreas Hultgren
80

Saya menemukan bahwa "solusi" hanya dengan meningkatkan timeout mengaburkan apa yang sebenarnya terjadi di sini, yang merupakan salah satunya

  1. Kode dan / atau panggilan jaringan Anda terlalu lambat (seharusnya sub 100 ms untuk pengalaman pengguna yang baik)
  2. Pernyataan (tes) gagal dan ada sesuatu yang menelan kesalahan sebelum Mocha mampu menindaklanjutinya.

Anda biasanya menemukan # 2 ketika Mocha tidak menerima kesalahan pernyataan dari panggilan balik. Ini disebabkan oleh beberapa kode lain yang menelan pengecualian lebih lanjut di stack. Cara yang tepat untuk menangani ini adalah memperbaiki kode dan tidak menelan kesalahan .

Ketika kode eksternal menelan kesalahan Anda

Jika fungsi pustaka yang tidak dapat Anda modifikasi, Anda perlu menangkap kesalahan pernyataan dan meneruskannya ke Mocha sendiri. Anda melakukan ini dengan membungkus panggilan balik pernyataan Anda dalam blok coba / tangkap dan berikan pengecualian apa pun kepada penangan yang sudah selesai.

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

Pelat ini tentu saja dapat diekstraksi menjadi beberapa fungsi utilitas untuk membuat tes ini sedikit lebih menyenangkan bagi mata:

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

Mempercepat tes jaringan

Selain itu saya sarankan Anda mengambil saran tentang mulai menggunakan test bertopik untuk panggilan jaringan untuk membuat tes lulus tanpa harus bergantung pada jaringan yang berfungsi. Menggunakan Mocha, Chai dan Sinon tes mungkin terlihat seperti ini

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

});

Lihat dokumen Sinonnise untuk info lebih lanjut.

oligofren
sumber
Saya memiliki serangkaian besar tes dan saya hanya pergi melalui semua janji dalam spesifikasi saya untuk memastikan mereka semua menelepon done()di akhir janji dan saya sudah mengejek panggilan jaringan menggunakan Angular $httpBackend, tetapi tidak berhasil. Membungkus setiap spec dengan try-catch sepertinya tidak pragmatis. Ada saran lain? Terima kasih!
Gustavo Matias
@ GustavoMatias Anda sebenarnya belum menyebutkan apa masalah Anda, hanya menyatakan bahwa ini bukan solusi untuk apa pun yang bermasalah. Tolong lakukan perincian :-) Apakah tes Anda tidak gagal cukup cepat? Apakah mereka terkadang gagal, tetapi Anda ingin tahu mengapa? Sulit menebak apa yang ingin Anda capai.
oligofren
hai @oligofren! memang itu bukan penjelasan terbaik. Ada penjelasan yang lebih rinci tentang masalah saya di sini stackoverflow.com/questions/34510048/... terima kasih!
Gustavo Matias
"Secara umum, cara terbersih (tapi paling jelek) cara menangani masalah ini adalah dengan membungkus kode Anda dengan coba / tangkap dan berikan pengecualian apa pun kepada penangan yang sudah selesai." Tidak, ini sama sekali bukan cara terbersih. Tidak terlalu jauh. Cara terbersih adalah menulis kode yang tidak menelan pengecualian. Setiap kali saya melihat seseorang mengeluh bahwa Mocha tidak mendeteksi tes yang gagal, itu karena ada sesuatu yang menelan pengecualian. Menambahkan try.... catch...karya di sekitar bug dalam kode yang sedang diuji alih-alih memperbaikinya .
Louis
@ Louis kamu mungkin benar tentang kenapa di sini, tapi aku tidak bisa memverifikasinya tiba-tiba. Lagi pula, orang-orang memiliki masalah dengan Mocha yang tampaknya tidak dapat menangkap beberapa kesalahan, dan ini adalah cara untuk menanganinya. pendekatan yang Anda berikan mengasumsikan bahwa kode yang menelan kesalahan bukanlah fungsi pustaka atau serupa, dalam hal ini tidak akan mudah dipecahkan.
oligofren
7

Sedikit terlambat tetapi seseorang dapat menggunakan ini di masa depan ... Anda dapat meningkatkan batas waktu pengujian dengan memperbarui skrip di package.json Anda dengan yang berikut:

"scripts": { "test": "test --timeout 10000" //Adjust to a value you need }

Jalankan tes Anda menggunakan perintah test

Daniel Mbeyah
sumber
Bekerja untukku! Terimakasih!
Ray tanpa cinta
5

Jika Anda menggunakan fungsi panah:

it('should do something', async () => {
  // do your testing
}).timeout(15000)
lukas_o
sumber
1

Bagi saya masalahnya sebenarnya adalah fungsi uraikan, yang ketika menyediakan fungsi panah, menyebabkan mocha kehilangan batas waktu, dan berperilaku tidak konsisten. (Menggunakan ES6)

karena tidak ada janji yang ditolak, saya mendapatkan kesalahan ini sepanjang waktu untuk berbagai tes yang gagal di dalam blok uraian

jadi begini tampilannya saat tidak bekerja dengan benar:

describe('test', () => { 
 assert(...)
})

dan ini berfungsi menggunakan fungsi anonim

describe('test', function() { 
 assert(...)
})

Semoga ini bisa membantu seseorang, konfigurasi saya untuk yang di atas: (nodejs: 8.4.0, npm: 5.3.0, mocha: 3.3.0)

syberkitten
sumber
0

Masalah saya adalah tidak mengembalikan respons, jadi itu menggantung. Jika Anda menggunakan express, pastikan res.send (data), res.json (data), atau apa pun metode api yang ingin Anda gunakan dijalankan untuk rute yang Anda uji.

il0v3d0g
sumber
0

Pastikan untuk menyelesaikan / menolak janji yang digunakan dalam kasus uji, baik itu mata-mata atau bertopik pastikan mereka menyelesaikan / menolak.

kavigun
sumber