node.js 在 mocha 测试中调用异步函数时如何避免超时 Error: timeout of 2000ms exceeded

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16607039/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 14:31:28  来源:igfitidea点击:

In mocha testing while calling asynchronous function how to avoid the timeout Error: timeout of 2000ms exceeded

node.jsmochachai

提问by sachin

In my node application I'm using mocha to test my code. While calling many asynchronous functions using mocha, I'm getting timeout error (Error: timeout of 2000ms exceeded.). How can I resolve this?

在我的节点应用程序中,我使用 mocha 来测试我的代码。使用 mocha 调用许多异步函数时,出现超时错误 ( 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();
        });

    });

});

回答by Andreas Hultgren

You can either set the timeout when running your test:

您可以在运行测试时设置超时:

mocha --timeout 15000

Or you can set the timeout for each suite or each test programmatically:

或者您可以以编程方式为每个套件或每个测试设置超时:

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

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

For more info see the docs.

有关更多信息,请参阅文档

回答by oligofren

I find that the "solution" of just increasing the timeouts obscures what's really going on here, which is either

我发现只是增加超时的“解决方案”掩盖了这里真正发生的事情,要么

  1. Your code and/or network calls are way too slow (should be sub 100 ms for a good user experience)
  2. The assertions (tests) are failing and something is swallowing the errors before Mocha is able to act on them.
  1. 您的代码和/或网络调用速度太慢(为了获得良好的用户体验,应该低于 100 毫秒)
  2. 断言(测试)失败,并且在 Mocha 能够对它们采取行动之前,某些东西正在吞噬错误。

You usually encounter #2 when Mocha doesn't receive assertion errors from a callback. This is caused by some other code swallowing the exception further up the stack. The right way of dealing with this is to fix the code and not swallow the error.

当 Mocha 没有从回调中收到断言错误时,您通常会遇到 #2。这是由其他一些代码将异常进一步吞入堆栈引起的。处理这个问题的正确方法是修复代码而不是吞下错误

When external code swallows your errors

当外部代码吞下你的错误时

In case it's a library function that you are unable to modify, you need to catch the assertion error and pass it onto Mocha yourself. You do this by wrapping your assertion callback in a try/catch block and pass any exceptions to the done handler.

如果它是一个您无法修改的库函数,您需要捕获断言错误并将其传递给 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);
    }
  });
});

This boilerplate can of course be extracted into some utility function to make the test a little more pleasing to the eye:

这个样板当然可以提取到一些实用函数中,使测试更赏心悦目:

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

Speeding up network tests

加快网络测试

Other than that I suggest you pick up the advice on starting to use test stubs for network calls to make tests pass without having to rely on a functioning network. Using Mocha, Chai and Sinon the tests might look something like this

除此之外,我建议您接受关于开始使用测试存根进行网络调用以使测试通过而不必依赖正常运行的网络的建议。使用 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;
    });

});

See Sinon's nisedocsfor more info.

有关更多信息,请参阅Sinon 的nise文档

回答by Daniel Mbeyah

A little late but someone can use this in future...You can increase your test timeout by updating scripts in your package.json with the following:

有点晚了,但将来有人可以使用它...您可以通过使用以下内容更新 package.json 中的脚本来增加测试超时:

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

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

Run your tests using the command test

使用命令运行您的测试 test

回答by lukas_o

If you are using arrow functions:

如果您使用箭头函数:

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

回答by syberkitten

For me the problem was actually the describe function, which when provided an arrow function, causes mocha to miss the timeout, and behave not consistently. (Using ES6)

对我来说,问题实际上是描述函数,当提供箭头函数时,它会导致 mocha 错过超时,并且行为不一致。(使用 ES6)

since no promise was rejected I was getting this error all the time for different tests that were failing inside the describe block

因为没有承诺被拒绝,所以我一直收到这个错误,因为在描述块内失败的不同测试

so this how it looks when not working properly:

所以这是它在不正常工作时的样子:

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

and this works using the anonymous function

这使用匿名函数

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

Hope it helps someone, my configuration for the above: (nodejs: 8.4.0, npm: 5.3.0, mocha: 3.3.0)

希望它对某人有所帮助,我的上述配置:(nodejs:8.4.0,npm:5.3.0,mocha:3.3.0)

回答by il0v3d0g

My issue was not sending the response back, so it was hanging. If you are using express make sure that res.send(data), res.json(data) or whatever the api method you wanna use is executed for the route you are testing.

我的问题是没有发回响应,所以它挂了。如果您使用 express 确保 res.send(data)、res.json(data) 或任何您想使用的 api 方法为您正在测试的路由执行。

回答by kavigun

Make sure to resolve/reject the promises used in the test cases, be it spies or stubs make sure they resolve/reject.

确保解决/拒绝测试用例中使用的承诺,无论是间谍还是存根,确保它们解决/拒绝。