你应该运行 Mocha--delay
选项,然后使用run()
一旦你完成了测试套件的构建。这是从您在问题中显示的代码派生的示例:
'use strict';
function test() {
console.log(1);
describe('Unit Testing', () => {
console.log(2);
it("test", () => {
console.log(3);
});
});
// You must use --delay for `run()` to be available to you.
run();
}
setTimeout(test, 1000);
我在用着setTimeout
模拟异步操作。使用--delay
and run()
允许您构建一个异步计算结果的套件。但请注意,该套件必须一次性构建。 (你不能在里面有一个异步进程describe
这将拨打电话it
。这行不通。)
rob3c 绝对不应该做的一件事是suggests https://stackoverflow.com/a/48572080/1906307: 打电话describe
or it
(或两者)从钩子内部。这是人们时常犯的错误,因此值得详细解决。问题是 Mocha 不支持它,因此没有与调用相关的既定语义describe
or it
从钩子里面。哦,可以编写简单的示例来按预期工作,但是:
当套件变得更加复杂时,套件的行为不再对应于任何明智的行为。
由于没有与此方法相关的语义,因此较新的 Mocha 版本可能会以不同的方式处理错误的使用并破坏您的套件。
考虑这个简单的例子:
const assert = require("assert");
const p = Promise.resolve(["foo", "bar", "baz"]);
describe("top", () => {
let flag;
before(() => {
flag = true;
return p.then((names) => {
describe("embedded", () => {
for (const name of names) {
it(name, () => {
assert(flag);
});
}
});
});
});
after(() => {
flag = false;
});
it("regular test", () => {
assert(flag);
});
});
当我们运行它时,我们得到:
top
✓ regular test
embedded
1) foo
2) bar
3) baz
1 passing (32ms)
3 failing
// [stack traces omitted for brevity]
这里发生了什么?不是所有的测试都应该通过吗?我们设置flag
to true
in the before
钩子top
描述。我们在其中创建的所有测试都应该看到flag
as true
, 不?线索在上面的输出中:当我们在钩子中创建测试时,Mocha 会将测试放入某处但它可能不在反映结构的位置describe
代码中的块。会发生什么在这种情况下是 Mocha 只是将钩子中创建的测试附加到套件的最后,在top
描述,所以after
hook 在动态创建的测试之前运行,我们得到了一个违反直觉的结果。
Using --delay
and run()
,我们可以编写一个行为符合直觉的套件:
const assert = require("assert");
const p = Promise.resolve(["foo", "bar", "baz"]).then((names) => {
describe("top", () => {
let flag;
before(() => {
flag = true;
});
after(() => {
flag = false;
});
describe("embedded", () => {
for (const name of names) {
it(name, () => {
assert(flag);
});
}
});
it("regular test", () => {
assert(flag);
});
});
run();
});
Output:
top
✓ regular test
embedded
✓ foo
✓ bar
✓ baz
4 passing (19ms)