【问题标题】:Mocha test executes callback twice on failureMocha 测试在失败时执行两次回调
【发布时间】:2014-02-10 11:12:43
【问题描述】:

我有一个简单的 Mongoose 模式,我正在使用 Mocha 进行测试;当我使用“成功”回调运行测试时,它正常执行,但是当最后一个测试执行时,它失败并似乎再次运行测试(我得到两个结论,一个填充错误对象,第二个在错误对象。)运行下面的两个测试会产生以下输出:

Cabinet: 
  â should return all authorized  
  â should return not authorized  <-- it succeeds the first time?
  1) should return not authorized 


2 passing (42ms)  
1 failing         <--- what?  there are only two tests

1) Cabinet:  should return not authorized :
   Uncaught AssertionError: expected null to exist  <--- see test

此测试重复

it("should return not authorized error ", function(done){
    var newCabinet = {
        name:  "A new cabinet",
        description: "Some remote cabinet",
        authorizedBorrowers : ["imatest","imanothertest"],
        cabinetInventory : []
    };
    Cabinet.newCabinet(newCabinet, function(err, cabinet){
        if (err) {
            console.log("Unable to create cabinet");
            done(err);
        }
        Cabinet.isAuthorizedBorrower(cabinet._id, "bob", function(cberr, borrower){
            should.exist(cberr);  <-- 'expected null to exist' points here
            done();
        });
    });
});

此测试有效

it("should not return unauthorized error ", function(done){
    var newCabinet = {
        name:  "A new cabinet",
        description: "Some remote cabinet",
        authorizedBorrowers : ["imatest","imanothertest"],
        cabinetInventory : []
    };
    Cabinet.newCabinet(newCabinet, function(err, cabinet){
        if (err) {
            console.log("Unable to create cabinet");
            done(err);
        }
        //console.log("ID " + cabinet._id)
        Cabinet.isAuthorizedBorrower(cabinet._id, "imatest", function(cberr, borrower){
            should.not.exist(cberr);
            done();
        });
    });
});

架构

var cabinetSchema = new Schema({
  name:  String,
  description: String,
  thumbnail : Buffer,
  authorizedBorrowers : [],
  defaultCheckout : {type : Number, default: 0} // default checkout mins = no time

});

var hasBorrower = function(cabinet, borrower){
  if (cabinet===null) return false;
  if (cabinet.authorizedBorrowers.length === 0) return false;
  return (cabinet.authorizedBorrowers.indexOf(borrower) >= 0)
}  

cabinetSchema.statics.isAuthorizedBorrower = function(cabinet_id, borrowername, cb ){
  this.findOne({_id: cabinet_id}, function(err, cabinet){
    if (err) cb(err,null);
    if (!hasBorrower(cabinet, borrowername)) cb(new Error(errorMsgs.borrowerNotAuthorized),null);
    cb(null,borrowername);
  });
};

【问题讨论】:

  • 我来到这里是因为出现在“应该”消息上的 (a + 抑扬符)字符。我发现我没有将控制台的输出(在我的例子中,Windows 10 下的 Git Bash)设置为 UTF-8,然后这个字符看起来像一个复选标记:

标签: node.js mongoose mocha.js


【解决方案1】:

无论何时执行此操作,请添加 return; 以避免两次调用 done 回调。这适用于 mocha,也适用于一般的 node.js 回调处理。

    if (err) {
        console.log("Unable to create cabinet");
        done(err);
        return;
    }

您的内阁架构中存在同样的问题:

if (err) cb(err,null);

这需要返回,否则它将调用回调两次并导致混乱(在 node.js 博客圈中也被亲切地称为“释放 Zalgo”的一种风格)。

【讨论】:

  • 按照您的建议修改其中一种模式方法,我能够完成这项工作:cabinetSchema.statics.isAuthorizedBorrower = function(cabinet_id, borrowername, cb ){ this.findOne({_id: cabinet_id}, function(err, cabinet){ if (err) cb(err,null); if (!hasBorrower(cabinet, borrowername)) { cb(new Error(errorMsgs.borrowerNotAuthorized),null); return; } cb(null,borrowername); }); };
  • 我不能说此时我理解为什么 - 尽管你的 cmets 我会彻底阅读这篇文章:blog.izs.me/post/59142742143/designing-apis-for-asynchrony
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
相关资源
最近更新 更多