为啥传递的函数是不是带参数对 Mocha 的 `before()` 很重要?

Posted

技术标签:

【中文标题】为啥传递的函数是不是带参数对 Mocha 的 `before()` 很重要?【英文标题】:Why does it matter to Mocha's `before()` whether the function passed takes parameters or not?为什么传递的函数是否带参数对 Mocha 的 `before()` 很重要? 【发布时间】:2018-01-27 12:47:48 【问题描述】:

我的describe:before(a)中有这样的代码。

a 看起来像这样时:

function a() 
  return chai.request(app)
    ...
    .then(res => 
      res.blah.should.blah;
      return Promise.resolve();
    );

...一切都很好(这是一个非常快速的调用。)

但是,当我让a 获取一些输入变量时:

function a(dummy, my_var) 
  return chai.request(app)
    ... // use my_var here
    .then(res => 
      res.blah.should.blah;
      console.log("finished!");
      return Promise.resolve();
    );

承诺永远不会解决。两个观察:

    finished! 确实得到正确的输出(立即) dummy 已填充。

它是这样填充的:

function (err) 
    if (err instanceof Error || toString.call(err) === '[object Error]') 
        return done(err);
    
    if (err) 
        if (Object.prototype.toString.call(err) === '[object Object]') 
            return done(new Error('done() invoked with non-Error: ' + JSON.stringify(err)));
        
        return done(new Error('done() invoked with non-Error: ' + err));
    
    if (result && utils.isPromise(result)) 
        return done(new Error('Resolution method is overspecified. Specify a callback *or* return a Promise; not both.'));
    
    done();

我不知道它的确切来源,但我不需要它,这就是为什么我将它放入一个虚拟变量中。

现在我怀疑这与它有关,但我想知道为什么我的解决方法在这里不起作用。

我仍然想使用before(a) 作为默认情况,留下my_var 未定义。当我确实想传递该变量时,我打算:

before(() => 
    return a('my_content');
  )

【问题讨论】:

【参考方案1】:

这是因为 Mocha 会检查您传递给 before 的函数以检查 defined on it 有多少参数,如下所示:

 this.async = fn && fn.length;

如果定义了任何参数,则该函数被认为是异步的。 (Mocha 还检查它是否返回一个 Promise,但这是一个不同的测试。)如果定义了至少一个参数,那么 Mocha 将作为第一个参数传递一个函数,当你的 before 回调完成它的工作时,你打算调用该函数。该回调(传统上称为done)对于不使用承诺的代码很有用。 如果你不调用它,那么即使你返回一个 promise,Mocha 也会永远等待。

请注意,Mocha 对所有其他钩子执行相同的操作:beforeEachafter 等,以及传递给 it 的回调。

【讨论】:

启发性的解释。那太糟糕了......那时没有向后兼容的方式来做我的改变。那好吧。谢谢!【参考方案2】:

Mocha before, after, it 函数接受一个参数 - 回调。当您的测试使用异步函数时,应该定义和调用它:

db.connect 是异步函数:

before(done => 
  db.connect(done);

db.connect 返回一个promise 时,你不应该使用回调并且可以返回promise:

before(() => 
  return db.connect();

在您的代码中,您使用a 函数调用before,该函数接受两个参数。 Mocha 将第一个参数解释为回调,并尝试调用它。

为防止出现此问题,您需要直接调用a 函数并在其中传递参数:

before(() => 
  return a(dummy, my_var);

【讨论】:

以上是关于为啥传递的函数是不是带参数对 Mocha 的 `before()` 很重要?的主要内容,如果未能解决你的问题,请参考以下文章

C语言问题,宏定义中的参数为啥要定义,不是主函数中的参数直接替换吗?

react 页面 参数怎么传递

为啥 Kotlin 允许编写不带参数的 main 函数?

为啥将函数作为函数的参数传递?

存储过程中参数是动态的,需要判断是不是为空

为啥数组不能作为函数参数传递?