摩卡.js:异步功能打破嵌套结构



当使用 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==5emailphone规范在另一个范围内(在这种情况下,范围是free describe(,那么这些规范将出现在顶部。

getUserData只是"等待"1ms,那么你可以看到emailphone规格,如果你将值增加到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();
});

相关内容

  • 没有找到相关文章

最新更新