为什么Mocha/Chai不将babel自定义错误与常规自定义错误一样对待?
Why don't Mocha/Chai treat babel custom errors the same as regular custom errors?
这适用于摩卡/Chai:
describe('Chai throw() with old-style custom errors', ()=> {
// old way
function ES5Error(message = 'todo', value) {
this.name = 'ES5Error';
this.message = message;
}
ES5Error.prototype = new Error();
it('catches ES5Errors', ()=> {
var err = new ES5Error('This is a bad function.');
var fn = function () { throw err; }
expect(fn).to.throw(ES5Error);
expect(fn).to.throw(Error);
expect(fn).to.throw(/bad function/);
expect(fn).to.not.throw('good function');
expect(fn).to.throw(ES5Error, /bad function/);
expect(fn).to.throw(err);
});
});
而基于类的方法没有:
describe('Chai throw() with new-style custom errors', ()=> {
// New way
class ExtendError extends Error {
constructor(message = 'todo', value) {
super(message);
this.name = 'ExtendError';
this.message = message;
}
}
it('catches ExtendError', ()=> {
var err = new ExtendError('This is a bad function.');
var fn = function () { throw err; }
expect(fn).to.throw(ExtendError);
expect(fn).to.throw(Error);
expect(fn).to.throw(/bad function/);
expect(fn).to.not.throw('good function');
expect(fn).to.throw(ExtendError, /bad function/);
expect(fn).to.throw(err);
});
});
我也在这里实现了相关的SO答案。虽然很有趣,但它仍然不适用于摩卡throws()
。我基本上很高兴使用ES5风格错误,但我只是不确定实际问题是什么。当我为ExtendError
编译代码时,我不能立即看到任何会绊倒expect子句的东西:
'use strict';
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass,
enumerable: false,
writable: true,
configurable: true
}
});
if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
}
var ExtendError = function (_Error) {
_inherits(ExtendError, _Error);
function ExtendError() {
var message = arguments.length <= 0 || arguments[0] === undefined ? 'todo' : arguments[0];
var value = arguments[1];
_classCallCheck(this, ExtendError);
var _this = _possibleConstructorReturn(this, _Error.call(this, message));
_this.name = 'ExtendError';
_this.message = message;
return _this;
}
return ExtendError;
}(Error);
摩卡/Chai的问题是什么?
问题不在Chai。如果你用ES6实现err instanceof ExtendError
,你会得到false
!
你运行的ExtendError
的ES5和ES6实现实际上是不同的。
-
在ES5端,调用
Error
,但对返回值不做任何操作。 -
在ES6端,
super(...)
调用被转换为var _this = _possibleConstructorReturn(this, _Error.call(this, message));`
,然后
_this
代替原来ES6代码中的this
。Error
的返回值是在ES6代码中使用的,这是一切都变得糟糕的地方,因为你从构造函数返回的对象是Error
对象,而不是ExtendError
对象。
我将继续使用ES5语法从Error
派生。我尝试了一些方法来保持ES6的语法,但最终它们都是混合的,或者做了非常糟糕的事情。我想到的最不令人反感的方法是:
class ExtendError {
constructor(message = 'todo', value) {
Error.call(this, message);
this.name = 'ExtendError';
this.message = message;
}
}
ExtendError.prototype = Object.create(Error.prototype);
ExtendError.prototype.constructor = ExtendError;
它没有充分利用ES6 class
糖…
相关文章:
- 是否排除节点中错误堆栈的第一行?/节点中的自定义错误类型
- 如何访问npm模块抛出的自定义错误对象[error:[object object]]
- 登录时显示自定义错误消息
- AJAX自定义错误处理代码问题
- jQuery验证自定义错误
- 来自元素属性的自定义错误消息:jQuery 验证插件
- 使用 $.post 对用户进行身份验证以返回自定义错误/成功消息
- 自定义错误显示在自定义位置,而不是每个元素旁边
- Jquery/php 输出自定义错误消息
- 通过jQuery在Html.ValidationMessageFor中显示自定义错误
- 在V8中从C++代码创建自定义错误类
- 自定义HTML5表单验证最初未显示自定义错误
- JQuery验证器自定义错误位置不起作用
- 如何在Sails.js中通过Hand构建非自定义错误
- 在Babel下调用super()时,由于自定义错误,无法输出堆栈
- 自定义错误和bluebird's与ErrorClass的捕获会导致意外行为
- 自定义错误格式
- 自定义错误对象与阿波罗服务器
- 如何在jquery验证插件中添加自定义错误替换消息
- 如何捕获一个错误,并在数据库中保存错误细节和重定向到自定义错误页面在经典asp