15

当我使用 Mocha 进行测试时,我经常需要同时运行异步和同步测试。

Mocha 很好地处理了这个问题,让我可以done在我的测试是异步的时候指定一个回调 , 。

我的问题是,Mocha 如何在内部观察我的测试并知道它应该等待异步活动?只要我在测试函数中定义了回调参数,它似乎就在等待。您可以在下面的示例中看到,第一个测试应该超时,第二个应该在user.save调用匿名函数之前继续并完成。

// In an async test that doesn't call done, mocha will timeout.
describe('User', function(){
  describe('#save()', function(){
    it('should save without error', function(done){
      var user = new User('Luna');
      user.save(function(err){
        if (err) throw err;
      });
    })
  })
})

// The same test without done will proceed without timing out.
describe('User', function(){
  describe('#save()', function(){
    it('should save without error', function(){
      var user = new User('Luna');
      user.save(function(err){
        if (err) throw err;
      });
    })
  })
})

这是 node.js 特有的魔法吗?这是可以在任何 Javascript 中完成的事情吗?

4

2 回答 2

22

这是简单的纯 Javascript 魔法。

函数实际上是对象,并且它们具有属性(例如用函数定义的参数数量)。

看看在 mocha/lib/runnable.js 中 this.async 是如何设置的

function Runnable(title, fn) {
  this.title = title;
  this.fn = fn;
  this.async = fn && fn.length;
  this.sync = ! this.async;
  this._timeout = 2000;
  this._slow = 75;
  this.timedOut = false;
}

Mocha 的逻辑会根据您的函数是否使用参数定义而改变。

于 2012-11-26T18:10:25.003 回答
4

您正在寻找的是 Function 的 length 属性,它可以告诉您一个函数需要多少个参数。当你用它定义一个回调时,done它可以异步地告诉和处理它。

function it(str, cb){
  if(cb.length > 0)
    //async
  else
    //sync
}

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/Length

于 2012-11-26T18:07:20.740 回答