测试可选对象成员的最佳技术是什么。现在我们正在使用if:
为expect语句添加前缀 if(object.member) expect(object).to.have.a.property('member').that.is.a('string');
但必须有一种风格更内联的方法。 E.g。
expect(object).to.have.an.optional.property('member').that.is.a('string');
或(为了便于阅读,添加为空链):
expect(object).to.have.an.optional.property('member').that.would.be.a('string');
或(移动可选项以提供expect的替代版本):
optionally.expect(object).to.have.a.property('member').that.is.a('string');
更新 - 我开始编写此代码(chai的新内容),看看我是否可以完成我的定位,所以我添加了一个小插件:
module.exports = function(chai, utils) {
var Assertion = chai.Assertion
, i = utils.inspect
, flag = utils.flag;
var OPTIONAL_FLAG = 'chai-optional/option'
Assertion.addProperty('optional', function() {
flag(this, OPTIONAL_FLAG, true)
return this;
})
Assertion.overwriteMethod('property', function (_super) {
return function assertProperty (propertyName) {
if (flag(this, OPTIONAL_FLAG)) {
flag(this, OPTIONAL_FLAG, false) ;
var obj = this._obj;
var isPropertyPresent = (obj[propertyName]) ? true : false ;
if(isPropertyPresent) {
return _super.apply(this, arguments);
}
} else {
_super.apply(this, arguments);
}
};
});
Assertion.addProperty('would', function () {
return this;
});
};
用法:
it('could be null or have a value', function(done){
var objWithout = {}
var objWith = {}
objWith.someProperty = 'blah'
expect(objWith).to.have.optional.property('someProperty').that.would.be.a('string');
expect(objWithout).to.have.optional.property('someProperty').that.would.be.a('string');
return done();
})
当前问题即使属性不存在,功能的控制也会结束 - 但评估链仍在继续。我需要在没有断言的情况下结束评估 - 这可能吗?
更新任一解决方案(简单化解决方案):
var either = function(firstCondition){
var returnObject = {}
try{
firstCondition()
returnObject.or = function(secondCondition){ return }
} catch(e) {
returnObject.or = function(secondCondition){ return secondCondition() }
}
return returnObject ;
}
module.exports = either
我认为实现有点笨重 - 但胖箭头功能会使一些语法变得稀疏。所以这里等着!
答案 0 :(得分:0)
当前问题即使属性不存在,函数的控制也会结束 - 但评估链仍在继续。我需要在没有断言的情况下结束评估 - 这可能吗?
在阅读了关于chai的plugin guide之后,我会使用类似的方法来标记。但是,我得出了同样的结论 - 你不能简单地停止链条。
我可能不仅要实现新属性和新标志,而且要覆盖assert
方法本身 - 当前{{1}上的OPTIONAL_FLAG
标志时不抛出对象已设置。然而,摧毁一切或错过边缘案件的机会太高了。
毕竟,我认为这不是一个好主意。引自this "confusing syntax" issue:
我认为这种误解来自你对柴的期望 遵循大多数/所有英语语法规则。不幸的是,英语语法 它有太多的规则(以及那些规则的例外),因为它是一个 合理的承诺实施。
设计Chai的可连锁断言的挑战在于寻找 表达和简洁之间的平衡。即使是完整的语法 实施和记录并不是一项艰巨的任务,它将成为 API不够简洁,这对测试环境不利。
规则:任何修改断言行为的“标志”(否定 一旦设置为true,则不包含include包含/包含等等 应该保持真实,直到链的末端。
这意味着不可能像Assertion
运算符那样实现。
虽然可以实现像
这样的东西.or
也许有人可以在其上构建更具吸引力的语法。