我正在为一个库编写测试套件,该库执行未处理catch
语句的异常的处理。该库会监听涓流到全球范围的error
事件(例如window.addEventListener("error", ...)
)。
但是,如果我想测试是否真的能够检测到未处理的异常,我不能,因为Mocha会将此类异常视为测试失败。我不能使用像expect(foo).to.throw
这样的断言,因为如果我使用这些断言,则expect
会抓取异常并且不再是未处理的异常 :它不会触发我的库安装的全局监听器以及我想要测试的全局监听器。
我已经尝试allowUncaught
,但这并没有解决问题。这是一个重现问题的示例测试:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/xhtml; charset=utf-8"/>
<link href="node_modules/mocha/mocha.css" type="text/css" media="screen" rel="stylesheet" />
<script src="node_modules/mocha/mocha.js"></script>
</head>
<body>
<div id="mocha"></div>
<script>
mocha.setup('bdd');
mocha.allowUncaught();
it("should be fine", function (done) {
// Simulate an error thrown by asynchronous code.
setTimeout(function () {
throw new Error("error");
}, 100);
// My actual error handler is bigger than this. This is just to
// simulate what my actual test suite does.
function listener(ev) {
// Uninstall ourselves.
window.removeEventListener("error", listener);
done(); // We detected the error: everything is fine.
}
window.addEventListener("error", listener);
});
mocha.run();
</script>
</body>
</html>
上述测试应该通过。然而,当我运行它时,摩卡报告了一次失败和一次成功!如何让Mocha忽略未捕获的异常并让我的自定义代码处理它?</ p>
答案 0 :(得分:4)
Mocha在window
上安装自己未处理的异常事件侦听器,而allowUncaught
并不会阻止它。您需要做的是使用以下命令卸载此处理程序:
Mocha.process.removeListener("uncaughtException");
这是暂时关闭Mocha的未处理异常处理的示例:
mocha.setup('bdd');
mocha.allowUncaught();
var savedHandler = undefined;
before(function () {
// Save Mocha's handler.
savedHandler = window.onerror;
});
describe("without handler", function () {
before(function () {
// Stop Mocha from handling uncaughtExceptions.
Mocha.process.removeListener("uncaughtException");
});
it("should be fine", function (done) {
setTimeout(function () {
throw new Error("error");
}, 100);
function listener(ev) {
window.removeEventListener("error", listener);
done();
}
window.addEventListener("error", listener);
});
after(function () {
// Restore the handler so that the next tests are treated as
// mocha treats them.
window.onerror = savedHandler;
});
});
describe("with handler", function () {
it("should fail", function (done) {
setTimeout(function () {
throw new Error("error");
}, 100);
});
});
mocha.run();
第一次测试将通过并且仅计算一次。正如我们所期望的那样,第二次测试将失败,因为Mocha的未处理异常处理程序已生效。
即使您只有一次测试,您获得一次通过和一次失败的原因是Mocha的一种特殊性。它检测未处理的异常,因此声明测试失败。但然后你的代码调用done
所以Mocha声明测试已经过去并计算两次。
请注意,上面使用的方法没有记录,可能会破坏未来的Mocha版本。据我所知,没有&#34;官方&#34;获得理想结果的方法。
答案 1 :(得分:-2)
在我看来,你真正反对的是一个设计问题。全球国家是单位测试的毒药。您必须摆脱对window
的硬编码依赖关系,以使您的代码易于测试。
也许你可以在实例化时让你的组件接受一个对象来附加自己。然后你可以测试agaist任意DOM元素。
或者,如果要对窗口对象进行测试,只需传入另一个窗口对象即可。您可以生成一个子窗口并使用它。摩卡应该没问题。 (拿着一点盐,我在我的一些测试中创建了子窗口,但是我没有在它们中触发未处理的异常。)