当使用 mocha 测试异步函数的结果时,await
之后的测试会从嵌套结构中弹出,就像下面的前 2 个测试一样:
✓ email
✓ phone
current unit
fetch data
✓ is 5==5
3 passing (10ms)
我们如何使测试出现在正确的位置?
代码:
const chai = require('chai');
chai.should();
describe ("current unit", async () => {
describe ("fetch data", async () => {
it ("is 5==5", () => { chai.expect(5).to.equal(5); });
const UserData = await getUserData("UserName");
it ("email", () => { UserData.email.should.equal("example@g.com"); });
it ("phone", () => { UserData.phone.should.equal("+1 (800) 123 4567"); });
});
});
function getUserData(param) { return new Promise(resolve => setTimeout(() => resolve({ email:"example@g.com",phone:"+1 (800) 123 4567" }), 1/*ms*/));}
如果你将代码从async/await
语法"转换"到 Promise 语法,解释起来会更清楚:
describe("current unit", () => {
describe("fetch data", () => {
it("is 5==5", () => { chai.expect(5).to.equal(5); });
getUserData("UserName")
.then(UserData => {
it("email", () => { UserData.email.should.equal("example@g.com"); });
it("phone", () => { UserData.phone.should.equal("+1 (800) 123 4567"); });
});
});
});
如您所见,"获取数据"仅包括is 5==5
,email
,phone
规范在另一个范围内(在这种情况下,范围是free describe
(,那么这些规范将出现在顶部。
getUserData
只是"等待"1ms,那么你可以看到email
,phone
规格,如果你将值增加到100ms(或更高(,你就不会这些规格,因为getUserData().then
是一个同步块。
切勿直接在describe
体内调用异步操作,让使用beforeEach
,或将其写入it
体中。
使用beforeEach
:
describe("current unit", () => { // remove async keyword, it does not make sense
let UserData; // define variable
beforeEach(async () => { // async
UserData = await getUserData("UserName"); // init
});
describe("fetch data", () => { // remove async keyword
it("is 5==5", () => { chai.expect(5).to.equal(5); });
it("email", () => { UserData.email.should.equal("example@g.com"); });
it("phone", () => { UserData.phone.should.equal("+1 (800) 123 4567"); });
});
});
current unit
fetch data
✓ is 5==5
✓ email
✓ phone
3 passing (357ms)
写入it
块:
describe("current unit", () => { // remove async keyword, it does not make sense
describe("fetch data", () => { // remove async keyword
it("is 5==5", () => { chai.expect(5).to.equal(5); });
it("should return correct email and phone", async () => { // compile into 1 spec
const UserData = await getUserData("UserName");
UserData.email.should.equal("example@g.com");
UserData.phone.should.equal("+1 (800) 123 4567");
});
});
});
current unit
fetch data
✓ is 5==5
✓ should return correct email and phone (108ms)
2 passing (149ms)
这是您使用before
的测试文件
const chai = require('chai');
chai.should();
describe ("current unit", async () => {
describe ("fetch data", async () => {
let UserData
before(async () => {
UserData = await getUserData("UserName");
})
it ("is 5==5", () => { chai.expect(5).to.equal(5); });
it ("email", () => { UserData.email.should.equal("example@g.com"); });
it ("phone", () => { UserData.phone.should.equal("+1 (800) 123 4567"); });
});
});
function getUserData(param) { return new Promise(resolve => setTimeout(() => resolve({ email:"example@g.com",phone:"+1 (800) 123 4567" }), 1/*ms*/));}
这是上述测试的输出
current unit
fetch data
✓ is 5==5
✓ email
✓ phone
您可以通过在"获取数据"测试套件中使用before
表达式使测试显示在正确的位置
您需要在测试的异步部分之后调用done()
函数。下面是一个示例:
it ("email", (done) => {
UserData.email.should.equal("example@g.com");
done();
});