Mocha 异步回调和 Sequelize promise 不同步?
Mocha async callback and Sequelize promise are not synchronize?
我正在使用 mocha 及其钩子 beforeEach
编写测试用例,它使用 sequelize.drop
和 sequelize.sync
.[=22= 删除并重新创建所有表]
lib/testutils.js
exports.deleteAll = function () {
return sequelize.drop({logging: false, cascade: true}).then(function() {
return sequelize.sync({logging: false});
});
};
test/controllers/controllers.js
(A) 这确实有效:
var testutils = require("../../lib/testutils");
describe("CRUD Controller", function() {
beforeEach(function(done) {
testutils.deleteAll().then(function(){
done();
}).catch(function(err) {
return done(err);
});
});
describe("#read()", function(){
it("should....", function(done) {
});
});
}
(B) 这没有用:
var testutils = require("../../lib/testutils");
describe("CRUD Controller", function() {
beforeEach(function(done) {
testutils.deleteAll().then(done).catch(function(err) {
return done(err);
});
});
describe("#read()", function(){
it("should....", function(done) {
});
});
}
我不明白为什么 testutils.deleteAll().then(done)
没有工作,第一个测试用例 it("should....", function(done)
没有等待 beforeEach
挂钩完成。我得到 TypeError: Converting circular structure to JSON
。但是,testutils.deleteAll().then(function(){ done(); })
确实有效。
我的问题是为什么 (B) 不工作而 (A) 工作?任何想法?有什么问题吗?
Mocha 支持 beforeEach 中的 promises 所以只写下面的代码:
beforeEach(function(){
return testutils.deleteAll();
});
你的 deleteAll()
函数 returns sequelize.sync()
returns 传递给它的承诺 this
。我认为上下文将是最后创建的模型,因此当您将函数传递给返回的 promise 时,该函数将传递最后创建的 table。因此,在情况 (A) 中,您指定了 function()
并手动调用 done()
而不将任何参数传递给 done()
。但是在情况 (B) 中,当您将 done 传递给 promise.then()
时,最后创建的模型将传递给 done。
要理解我的意思,请考虑以下内容:
User.create({name: 'aName'}).then(function(user){console.log(user)});
等同于
User.create({name: 'aName'}).then(console.log);
用户将自动传递给console.log()
。
所以 done
正在传递最后创建的模型,我认为这可能会导致问题。
当你直接传递 done
时,它接收到从 deleteAll
返回的对象,mocha 将其视为错误,因此它尝试将 JSON.stringify
应用于该对象并将其显示为错误,但不知何故 JSON.stringify
无法做到,所以它抛出异常,您可以看到。
你可以在Mocha::Runnable#run
中清楚地看到它
我正在使用 mocha 及其钩子 beforeEach
编写测试用例,它使用 sequelize.drop
和 sequelize.sync
.[=22= 删除并重新创建所有表]
lib/testutils.js
exports.deleteAll = function () {
return sequelize.drop({logging: false, cascade: true}).then(function() {
return sequelize.sync({logging: false});
});
};
test/controllers/controllers.js
(A) 这确实有效:
var testutils = require("../../lib/testutils");
describe("CRUD Controller", function() {
beforeEach(function(done) {
testutils.deleteAll().then(function(){
done();
}).catch(function(err) {
return done(err);
});
});
describe("#read()", function(){
it("should....", function(done) {
});
});
}
(B) 这没有用:
var testutils = require("../../lib/testutils");
describe("CRUD Controller", function() {
beforeEach(function(done) {
testutils.deleteAll().then(done).catch(function(err) {
return done(err);
});
});
describe("#read()", function(){
it("should....", function(done) {
});
});
}
我不明白为什么 testutils.deleteAll().then(done)
没有工作,第一个测试用例 it("should....", function(done)
没有等待 beforeEach
挂钩完成。我得到 TypeError: Converting circular structure to JSON
。但是,testutils.deleteAll().then(function(){ done(); })
确实有效。
我的问题是为什么 (B) 不工作而 (A) 工作?任何想法?有什么问题吗?
Mocha 支持 beforeEach 中的 promises 所以只写下面的代码:
beforeEach(function(){
return testutils.deleteAll();
});
你的 deleteAll()
函数 returns sequelize.sync()
returns 传递给它的承诺 this
。我认为上下文将是最后创建的模型,因此当您将函数传递给返回的 promise 时,该函数将传递最后创建的 table。因此,在情况 (A) 中,您指定了 function()
并手动调用 done()
而不将任何参数传递给 done()
。但是在情况 (B) 中,当您将 done 传递给 promise.then()
时,最后创建的模型将传递给 done。
要理解我的意思,请考虑以下内容:
User.create({name: 'aName'}).then(function(user){console.log(user)});
等同于
User.create({name: 'aName'}).then(console.log);
用户将自动传递给console.log()
。
所以 done
正在传递最后创建的模型,我认为这可能会导致问题。
当你直接传递 done
时,它接收到从 deleteAll
返回的对象,mocha 将其视为错误,因此它尝试将 JSON.stringify
应用于该对象并将其显示为错误,但不知何故 JSON.stringify
无法做到,所以它抛出异常,您可以看到。
你可以在Mocha::Runnable#run