为什么传递的函数是否接受参数对 Mocha 的 `before()` 很重要?
Why does it matter to Mocha's `before()` whether the function passed takes parameters or not?
我的 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');
})
那是因为 Mocha 检查你传递给 before
的函数来检查有多少参数是 defined on it 像这样:
this.async = fn && fn.length;
如果定义了任何参数,则该函数被认为是异步的。 (Mocha 还检查它是否 return 是一个承诺,但这是一个不同的测试。)如果至少定义了一个参数,那么 Mocha 将作为第一个参数传递一个你打算在 before
回调时调用的函数完成它的工作。该回调(传统上称为 done
)对于不使用 promises 的代码很有用。
如果你不调用它,那么即使你 return 一个承诺,Mocha 也会永远等待。
请注意,Mocha 对所有其他挂钩执行相同的操作:beforeEach
、after
等,以及您传递给 it
的回调。
Mocha before
、after
、it
函数接受一个参数——回调。当您的测试使用异步函数时,应该定义和调用它:
db.connect
是异步函数:
before(done => {
db.connect(done);
}
当 db.connect
return 是您不应该使用回调的承诺时,可以 return 承诺:
before(() => {
return db.connect();
}
在您的代码中,您使用 a
函数调用 before
,该函数接受两个参数。 Mocha 将第一个参数解释为回调,并尝试调用它。
为了防止这个问题,您需要直接调用a
函数并在其中传递参数:
before(() => {
return a(dummy, my_var);
}
我的 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');
})
那是因为 Mocha 检查你传递给 before
的函数来检查有多少参数是 defined on it 像这样:
this.async = fn && fn.length;
如果定义了任何参数,则该函数被认为是异步的。 (Mocha 还检查它是否 return 是一个承诺,但这是一个不同的测试。)如果至少定义了一个参数,那么 Mocha 将作为第一个参数传递一个你打算在 before
回调时调用的函数完成它的工作。该回调(传统上称为 done
)对于不使用 promises 的代码很有用。
如果你不调用它,那么即使你 return 一个承诺,Mocha 也会永远等待。
请注意,Mocha 对所有其他挂钩执行相同的操作:beforeEach
、after
等,以及您传递给 it
的回调。
Mocha before
、after
、it
函数接受一个参数——回调。当您的测试使用异步函数时,应该定义和调用它:
db.connect
是异步函数:
before(done => {
db.connect(done);
}
当 db.connect
return 是您不应该使用回调的承诺时,可以 return 承诺:
before(() => {
return db.connect();
}
在您的代码中,您使用 a
函数调用 before
,该函数接受两个参数。 Mocha 将第一个参数解释为回调,并尝试调用它。
为了防止这个问题,您需要直接调用a
函数并在其中传递参数:
before(() => {
return a(dummy, my_var);
}