0

我正在使用mocha及其钩子编写测试用例,该钩子使用andbeforeEach删除并重新创建所有表。sequelize.dropsequelize.sync

lib/testutils.js

exports.deleteAll = function () {
    return sequelize.drop({logging: false, cascade: true}).then(function() {
        return sequelize.sync({logging: false});
    });
};

测试/控制器/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)工作?任何想法?有什么不对?

4

3 回答 3

3

Mocha 在 beforeEach 中支持 Promise,所以只需编写以下代码:

beforeEach(function(){
  return testutils.deleteAll();
});
于 2015-01-20T07:35:15.473 回答
1

您的deleteAll()函数返回sequelize.sync()它返回一个传递它的承诺this。我认为上下文将是最后创建的模型,因此当您将函数传递给返回的承诺时,该函数将传递最后创建的表。因此,如果 (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通过了我认为可能会导致问题的最后一个模型。

于 2015-03-12T03:09:19.590 回答
0

当您done直接传递时,它会接收从 中返回的对象deleteAll,并且 mocha 将其视为错误,因此它尝试应用于JSON.stringify此对象并将其显示为错误,但不知何故JSON.stringify无法做到,因此它会抛出您可以看到的异常。你可以清楚地看到它Mocha::Runnable#run

于 2017-11-21T17:38:35.220 回答