Node.js/Mocha 中的轻松错误模拟






4.67/5 (2投票s)
在 Node.js/Mocha/Istanbul 中轻松模拟错误,以实现完整的代码覆盖率
引言
编写 Node.js 代码的单元测试非常重要,几乎是强制性的。我使用 Mocha 进行单元测试,并使用 Istanbul 生成代码覆盖率报告。
自然地,人们希望尽可能覆盖更多的代码。有些分支很难覆盖,特别是那些处理致命错误的分支,例如来自 MongoDB 驱动程序的致命错误,例如网络连接丢失。我想要一种简单、快速且易于覆盖这些分支的方法。我之前的 文章 描述了如何在 JavaScript 中创建代理模式。我将在这里使用相同的代理模式,为我希望抛出模拟错误的对象添加代理。
创建错误模拟器代理
在我的 之前的文章 中,有一个通用的 JavaScript 代理模式。我将使用该模式来创建一个错误模拟器。代理函数通过获取类的构造函数并重写每个函数到一个新函数来修改类。这个新函数将正确调用前/后事件以及类的原始函数。在这种情况下,前/后事件将是检查错误模拟的函数,如果需要错误模拟,则会抛出错误(或通过回调发送)。
一旦你对一个类使用错误模拟器函数,就会向其添加两个新函数
mockfailAfter(count, throwException) {...}
和
mockfailOnFunctionName(fname, throwException) {...}
mockfailOnFunctionName
接受一个函数名,在这种情况下,你输入应该在下次调用时失败的函数名。throwException
是一个布尔值,用于指示你希望该函数如何失败,如果设置为 true
,则会引发异常,如果设置为 false
,则应该存在一个回调函数,该函数将使用错误调用。mockfailAfter
函数的使用略有不同,不是给它一个函数名,而是给它一个 count
,这个 count
每次调用目标类的任何函数时都会减少,一旦达到零,它就会模拟错误。这些两个函数是我在撰写本文时所需要的全部,但是你可以轻松添加更多适合你需求的功能(文件 ErrorMocker.js)。例如,你可以创建一个将函数名失败和该函数名的调用次数结合起来的函数,或者可能是一个函数名和该函数的参数的特定值...
Using the Code
由于本文针对 Node.js 环境,你可以下载文件并立即使用它们。你需要的主要文件是 proxy.js 和 ErrorMocker.js。如果你需要在其他 JavaScript 用途中使用它们,可能需要稍微修改它们。
在你的单元测试文件中,你需要 ErrorMocker.js
var ErrorMocker = require("./ErrorMocker.js");
对于你想要模拟错误的每个类,你必须将代理模式附加到它,通常你会在 Mocha 的 before
部分执行此操作,如下所示
before(function(done) {
ErrorMocker(/* constructor of JavaScript class goes here */);
}
之后,你可以使用上面提到的两个函数。下面的代码是一个示例 Mocha 文件,展示了如何使用这些函数。
// sample unit testing file in node.js, using mocha and later istanbul for coverage
<pre>'use strict';
var should = require('should');
var errorMocker = require("./ErrorMocker.js");
var HttpHelper = require("./HttpHelper.js"); // for this sample,
// I choose a class called HttpHelper
var httpHelper = new HttpHelper();
describe('Sample Mocha Unit testing file', function() {
before(function(done) {
errorMocker(httpHelper);
});
describe('Doing tests section 1', function() {
it('Sample test on an httpHelper class that will fail a post request', function(done) {
httpHelper.mockfailOnFunctionName("postJson", false);
httpHelper.createPost(
"http://rest.sampleservice.com/api/somefunction/").postJson
(data, function (err, result) {
// here this function call will fail with an error in the callback function,
// effectively testing the error branch(es) inside HttpHelper
should.exist(err);
should.equal(err.message, "Error: mocker error");
done();
});
});
});
});
历史
- 2013 年 11 月 21 日:初始版本