对于异步测试和挂钩,请确保" done()"叫做;如果返回Promise,请确保其解析

时间:2017-05-24 04:39:00

标签: node.js mocha

我在测试时对nodejs进行了测试,我得到了未声明的完成函数的错误。

Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.

我的测试代码是,我已完成回调但仍然收到错误以致电done();

    it('remove existing subdocument', (done) => {
    const Vic = new User({
      name: 'Vic',
      posts: [{ title: 'Leaning Nodejs' }]
    });

    vic.save()
      .then(() => User.findOne({ name: 'Vic' }))
      .then((user) => {
        const post = user.posts[0];
        post.remove();
        return user.save();
      })
      .then(() => User.findOne({ name: 'Vic' }))
      .then((user) => {
        assert(user.posts.length === 0);
        done();
      });
  });

16 个答案:

答案 0 :(得分:16)

我遇到了同样的问题,@ MFAL的评论链接有所帮助。我正在扩展它。

如果出现错误/错误断言,则会在promise中引发错误。这导致承诺拒绝。一旦拒绝完成,从未调用过,mocha报告超时。 我通过编写.catch块并将其与承诺链接来解决这个问题:

          it('resolves', (done) => {
            fooAsyncPromise(arg1, arg2).then((res, body) => {
                expect(res.statusCode).equal(incorrectValue);
                done();
            }).catch(done);
         });

Wietse's blog中提到的其他方式是:

链接一个then(done, done)来处理解除和拒绝承诺。

         it('resolves', (done) => {
           resolvingPromise.then( (result) => {
             expect(result).to.equal('promise resolved');
           }).then(done, done);
         });

回复承诺:

        it('resolves', () => {
          return resolvingPromise.then( (result) => {
            expect(result).to.equal('promise resolved');
          });
        });

使用async / wait:

        it('assertion success', async () => {
          const result = await resolvingPromise;
          expect(result).to.equal('promise resolved'); 
        });

答案 1 :(得分:12)

我知道这样做很丑陋,只需将Mocha的默认超时时间从 2秒增加到10秒 ,就可以通过添加标记--timeout来完成测试脚本中为10000,即-

package.json

 "scripts": {
    "start": "SET NODE_ENV=dev && node server.js",
    "test": "mocha --timeout 10000"
  }

答案 2 :(得分:3)

如果以上方法均无济于事,请尝试摆脱“完成”并改用async function()

it("Test Post Request", async function () {
    _code_
})

答案 3 :(得分:1)

您可以将超时添加到特定测试中,以增加/覆盖2秒的默认超时。我遇到了同样的问题,但是可以通过以下方式通过它:

it('Test', (done) => { 
//your code  
done();
}).timeout(10000);

答案 4 :(得分:1)

在package.json文件中 您可以使用--timeout 1500修复此错误 就像我在下面使用的一样。

"scripts": {
  "start": "node server/server.js",
  "test": "export NODE_ENV=test || SET \"NODE_ENV=test\" && mocha --timeout 15000 server/**/*.test.js",
  "test-watch": "nodemon --exec 'npm test'"
   }

由于摩卡咖啡而发生此错误。

答案 5 :(得分:1)

我也遇到了这个错误,经过数小时的研究和调试,我找到了根本原因。

考虑此测试:

const delay = require('delay')

describe('Test', function() {
    it('should resolve', async function(done) {
      await delay(1000)
    })
})

运行测试时,出现此错误:

Error: Timeout of 2000ms exceeded. For async tests and hooks, ensure "done()" is called; if returning a Promise, ensure it resolves.

现在考虑这种稍有不同的测试,其中完成参数被删除

const delay = require('delay')

describe('Test', function() {
    it('should resolve', async function() {
      await delay(1000)
    })
})

运行此测试时,它会通过。

异步方法中 done 参数的存在以某种方式破坏了测试,即使它没有被使用,即使 done()在末尾被调用测试。

使用Mocha版本 7.2.0

答案 6 :(得分:1)

我有同样的错误信息,在我的例子中是由于使用了 sinon.useFakeTimers()

该调用与我的代码中使用的 setTimeout() 冲突。删除后一切正常。

答案 7 :(得分:0)

想法是增加超时时间。
另一种方法是仅在必需的方法中执行此操作:

{{1}}

这可以帮助我解决问题。

答案 8 :(得分:0)

当我回来维护从Node6到Node 13的旧节点模块时,我很高兴。修复很简单:

  • 在测试文件夹下添加文件mocha.opts
  • 此文件的内容为一行:--timeout 10000

答案 9 :(得分:0)

如果在VS Code扩展开发中遇到此错误,则需要将timeout添加到src/test/suite/index.ts中的Mocha实例中,例如:

// Create the mocha test
const mocha = new Mocha({
    ui: 'tdd',
    color: true,
    timeout: 10000 // Your application ideal timeout here
});

答案 10 :(得分:0)

我有同样的错误,这实际上是因为我通过了done并且在那时调用了done。因此,删除完成将使测试通过。我在测试路线中调用了async函数

答案 11 :(得分:0)

@Simon Boudrias在这里Why am I getting "Error: Resolution method is overspecified"?的回答对我有用。我只是想起了通过调用await Promise.resolve()最初想得到的after(async () => driver && driver.quit());而已,它会清理掉一切并正确存在。当然,别忘了将.timeout(10000);设置为所需的任何时间,以防万一您需要比默认2000多的时间来运行测试。

答案 12 :(得分:0)

我的问题是超时本身(扩展它无济于事),所以我的解决方案是

it("it should test methods",function(){
     this.timeout(0);
   });

如您所见,您不需要done参数

答案 13 :(得分:0)

你可以使用

  • 异步等待,
  • 返回 Promise-then,
  • 功能(完成)-完成()

在每种情况下都有超时

  • 全局超时,可以由命令参数给出,如下所示

  • 作为链方法或参数给出的函数超时(before/after[each|all],it)

    /usr/bin/node ./node_modules/mocha/bin/_mocha -u bdd --colors /home/cemt/cli-js/test/**/*.spec.js

测试代码:

describe('NSSF', function () {

    var a = 0

    beforeAll(async function () {
        console.log(">>> 1. a: ", a);
        await new Promise((resolve, reject) => {
            var intt = setInterval(() => {
                console.log(">>> a: ", ++a);
                if (a == 10) {
                    clearInterval(intt)
                    resolve();
                }
            }, 800);
        });
    }, 12000);

    it('a should be set to 1', () => {
        console.log("-----1");
        return new Promise(resolve => {
            console.log("-----2");
            setTimeout(() => {
                resolve(1)
            }, 14000)
        }).then(a => {
            expect(a === 1);
        })
    }, 3000);
})

没有超时设置:

enter image description here

带超时设置:

/usr/bin/node ./node_modules/mocha/bin/_mocha --slow 5000 -u bdd --timeout 10000 --colors /home/cemt/cli-js/test/**/*.spec.js

enter image description here

在 VS Code 中启动.json

enter image description here

答案 14 :(得分:0)

来自官方 Mocha 页面 (Mocha page)-> 在启动 mocha 时使用 next 标志:

--超时,-t v6.0.0 中的更新:使用检查标志调用 Mocha 时隐含 --no-timeout。相当于 --timeout 0。 --timeout 99999999 不再需要。

指定测试用例超时,默认为两 (2) 秒(2000 毫秒)。超过此时间的测试将被标记为失败。

要覆盖,您可以以毫秒为单位传递超时值,或带有 s 后缀的值,例如 --timeout 2s 和 --timeout 2000 是等效的。

要禁用超时,请使用 --no-timeout。

注意:同步(阻塞)测试也受超时限制,但在代码停止阻塞之前它们不会完成。无限循环还是无限循环!

答案 15 :(得分:0)

我遇到了同样的问题。我的代码中有一个 .each()。修复它所需要的只是添加 before 作为 this.timeout(0); 函数的第一行,并在整个文件中使用 async-await 并删除 before